// This file is a part of the xMule Project.
//
// Copyright (c) 2004 Theodore R. Smith (hopeseekr@xmule.ws / http://www.xmule.ws/)
// DSA-1024 Fingerprint: 10A0 6372 9092 85A2 BB7F 907B CB8B 654B E33B F1ED
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

#include <iostream>                         // Needed for std::cout std::endl
#include <string>                           // Needed for std::string

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

using std::cout;
using std::endl;

static const char* VERSION = "2.0";

void AddLink(const char* ed2klink)
{
    FILE *ed2kfile;
    char filename[256];

    sprintf(filename, "%s/.xMule/ED2KLinks", getenv("HOME"));
    ed2kfile = fopen(filename, "a");

    if (ed2kfile != NULL)
    {
        fprintf(ed2kfile, "%s\n", ed2klink);
        cout << "Successfully wrote ED2K link to file." << endl;
        fclose(ed2kfile);
    }
    else
    {
        cout << "Error opening file " << filename << "." << endl;
    }
}

bool IsValidURL(std::string uri)
{
    // Parse pseudo-URI
    const char* pChArray[7];

    if (uri.empty())
    {
        throw std::string("NULL ED2K Link");
    }

    std::string pNewString = uri;
    char* pCh = new char[pNewString.length()];
    strcpy(pCh, pNewString.c_str());
    const char* pStart = pCh;

    int idx = 0;

    for (idx = 0; idx < 7; ++idx)
    {
        pChArray[idx] = NULL;
    }

    idx = 0;
    
    while (idx < 7 && ((pCh = strchr(pCh, '|')) != 0))
    {
        pChArray[idx++] = pStart;
        *pCh = 0;
        ++pCh;
        pStart = pCh;
    }

    if (*pStart != '/')
    {
        throw std::string("not a well-formed ED2K link");
    }

    if (idx < 3 || 
/*->*/  pChArray[0] == 0 || 
/*->*/  pChArray[1] == 0 || 
/*->*/  pChArray[2] == 0 || 
/*->*/  strcmp("ed2k://", pChArray[0]) != 0)
    {
        throw std::string("not a well-formed ED2K link");
    }
    if (strcmp("file", pChArray[1]) == 0 && idx >= 5 && pChArray[4] != 0)
    {
        return true;
    }
    else if (strcmp("serverlist", pChArray[1]) == 0 && idx == 3)
    {
        return true;
    }
    else if (strcmp("server", pChArray[1]) == 0 && idx == 4)
    {
        return true;
    }
    else
    {
        throw std::string("Not an ED2K server or file link");
    }

    return false;
}

int main(int argc, char *argv[])
{
    int result = 0;

    for (int i = 1; i < argc; ++i)
    {
        std::string link(argv[i]);

        if (link.find("ed2k://") == 0)
        {
            if (IsValidURL(link) == true)
            {
                AddLink(link.c_str());
            }
        }
        else if (link == "--version")
        {
            cout << "xMule ED2k Link Parser " << VERSION << endl;
        }
        else if (link == "--help")
        {
            cout << "xMule ED2K links parser v1.0" << endl << endl;
            cout << "Enter ED2K links as commandline arguments, and they will be saved into $HOME/.xMule/ED2KLinks" << endl;
            cout << "file, from where xMule will pick them up and add to download queue once per second." << endl;
            cout << "Currently, only file links are supported." << endl << endl;
            cout << "Usage:" << endl;
            cout << "       --help          Prints this help." << endl;
            cout << "       --version       Displays version info." << endl;
            cout << "       ed2k://|file|   Sends ED2k link to $HOME/.xMule/ED2KLinks file." << endl;
        }
        else
        {
            if (link.length() <= 55)
            {
                cout << "Invalid ED2K Link.\nReason: Link length is below 55 characters." << endl;
            }

            result = 1;
        }
    }

    return result;
}

