/*
This source file is part of Scol
For the latest info, see http://www.scolring.org

Copyright (c) 2011 Stephane Bisaro, aka Iri <iri@irizone.net>

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser 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 Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/copyleft/lesser.txt

For others informations, please contact us from http://www.scolring.org/
*/


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "weather.h"

char* weather_connection_read (SOCKET sock, SConnDatas datas);
int weather_connection_write (SOCKET sock, char *cmd);

/* blurps */
static int weather_ftp_get_XYZ (SOCKET sock, SConnDatas datas, char **reply)
{
    char *s;
    int k;

    *reply = weather_connection_read (sock, datas);

    s = malloc (sizeof (char)*5);
    snprintf (s, 4, "%s", *reply);
    k = atoi (s);
    free (s);
    return k;
}


/* A refaire proprement ! */
static void weather_ftp_ipport (char *buffer, char **p_ip, int *p_port)
{
    char *a;
    char b[5];
    char ip[16];
    int p;

    ip[0] = '\0';
    a = 1+strchr (buffer, '(');
    p = searchCharMem (a, ')');
    a[p] = '\0';
    p = searchCharMem (a, ',');
    strncpy (ip, a, p);
    ip[p] = '\0';
    a = strchr (a+1, ',');
    p = searchCharMem (a+1, ',');
    strncat (ip, a+1, p);
    a = strchr (a+1, ',');
    p = searchCharMem (a+1, ',');
    strncat (ip, a+1, p);
    a = strchr (a+1, ',');
    p = searchCharMem (a+1, ',');
    strncat (ip, a+1, p);
    ip[strlen (ip)-1] = '\0';
    replaceChar ((char *) ip, ',', '.');

    a = strchr (a+1, ',');
    p = searchCharMem (a+1, ',');
    strncpy (b, a+1, p);
    *p_port = 256 * atoi (b);
    a = strchr (a+1, ',');
    p = searchCharMem (a+1, ')');
    strncpy (b, a+1, p);
    *p_port += atoi (b);

    strncpy (*p_ip, ip, 16);
    return;
}

static int weather_create_sockdatas (char *ip, int port)
{
    SOCKET sockdatas;
    SOCKADDR_IN address = { 0 };

    if (1 == weather_connection_init())
        return -1;

    sockdatas = socket (AF_INET, SOCK_STREAM, 0);
    if (sockdatas == INVALID_SOCKET)
    {
        MMechostr (MSKDEBUG, "weather_create_sockdatas error : socket invalid = %d", sockdatas);
        weather_connection_end (-1);
        return -1;
    }
    address.sin_port = htons (port);
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr (ip);
    if (INADDR_NONE == address.sin_addr.s_addr)
        MMechostr (MSKDEBUG, "weather_create_sockdatas error : address IP not converted (inet_addr)\n");
    if (connect (sockdatas, (SOCKADDR *) &address, sizeof (address)) == SOCKET_ERROR)
    {
        MMechostr (MSKDEBUG, "weather_create_sockdatas error : not connected : %d, %s!\n", errno, strerror (errno));
        weather_connection_end (sockdatas);
        return -1;
    }
    return sockdatas;
}


void weather_ftp_read_datametar (SOCKET sockdatas, SConnDatas datas)
{
    char *buffer = NULL;
    int code;

    code = weather_ftp_get_XYZ (sockdatas, datas, &buffer);

    MMechostr (MSKDEBUG, "weather_ftp_read_datametar : result %s\n", buffer);
    MMechostr (MSKDEBUG, "weather_ftp_read_datametar : ftp error %d\n", code);
    datas->buffer[strlen(buffer)-1] = '\0';
    free (buffer);
    return;
}

void weather_ftp_read_metar (SOCKET sock, SConnDatas datas)
{
    char *buffer = NULL;
    int code;

    code = weather_ftp_get_XYZ (sock, datas, &buffer);
    if (code == 150)
    {
        MMechostr (MSKDEBUG, "weather_ftp_read_metar : YESSSS\n");
    }
    MMechostr (MSKDEBUG, "weather_ftp_read_metar : result %s\n", buffer);
    MMechostr (MSKDEBUG, "weather_ftp_read_metar : ftp error %d\n", code);
    free (buffer);
    return;
}

void weather_ftp_read_cwd (SOCKET sock, SConnDatas datas, SOCKET sockdatas)
{
    char *buffer = NULL;
    int code;

    code = weather_ftp_get_XYZ (sock, datas, &buffer);
    if (code == 250)
    {
        char *cmd = "RETR LFML.TXT";
        if (weather_connection_write (sock, cmd) != -1)
        {
            weather_ftp_read_datametar (sockdatas, datas);
            weather_ftp_read_metar (sock, datas);
        }
        return;
    }
    /*MMechostr (MSKDEBUG, "weather_ftp_read_cwd : result %s\n", buffer);
    MMechostr (MSKDEBUG, "weather_ftp_read_cwd : ftp error %d\n", code);*/
    free (buffer);
    return;
}


void weather_ftp_read_pasv (SOCKET sock, SConnDatas datas)
{
    char *buffer = NULL;
    int code;

    /*buffer = weather_connection_read (sock, datas);

    code = weather_ftp_get_XYZ (buffer);*/
    code = weather_ftp_get_XYZ (sock, datas, &buffer);
    if (code == 227)
    {
        int port, len;
        char *ip = NULL, *cmd = NULL;
        SOCKET sockdatas;

        ip = malloc (sizeof (char) * 16);
        weather_ftp_ipport (buffer, &ip, &port);
        MMechostr (MSKDEBUG, "weather_ftp_read_pasv : ip %s  port %d\n", ip, port);

        sockdatas = weather_create_sockdatas (ip, port);
        free (ip);
        if (sockdatas == -1)
            MMechostr (MSKDEBUG, "weather_ftp_read_pasv error : datas socket not created\n");
        len = strlen (datas->url)+5;
        cmd = malloc (sizeof (char) * len);
        memset (cmd, len, '\0');
        snprintf (cmd, len, "CWD %s", datas->url);
        MMechostr (MSKDEBUG, "weather_ftp_read_pasv : cmd %s\n", cmd);
        if (weather_connection_write (sock, cmd) != -1)
            weather_ftp_read_cwd (sock, datas, sockdatas);
        free (cmd);
    }
    MMechostr (MSKDEBUG, "weather_ftp_read_pasv : ftp error %d\n", code);
    free (buffer);
    return;
}

void weather_ftp_read_pass (SOCKET sock, SConnDatas datas)
{
    char *buffer = NULL;
    int code;

    code = weather_ftp_get_XYZ (sock, datas, &buffer);
    if (code == 230)
    {
        char *cmd = "PASV";
        if (weather_connection_write (sock, cmd) != -1)
            weather_ftp_read_pasv (sock, datas);
        return;
    }
    MMechostr (MSKDEBUG, "weather_ftp_read_pass : ftp error %d\n", code);
    free (buffer);
    return;
}

void weather_ftp_read_user (SOCKET sock, SConnDatas datas)
{
    char *buffer = NULL;
    int code;

    code = weather_ftp_get_XYZ (sock, datas, &buffer);
    if (code == 331)
    {
        char *cmd = "PASS scolEngine";
        if (weather_connection_write (sock, cmd) != -1)
            weather_ftp_read_pass (sock, datas);
        return;
    }
    MMechostr (MSKDEBUG, "weather_ftp_read_user : ftp error %d\n", code);
    free (buffer);
    return;
}

void weather_ftp_read_connect (SOCKET sock, SConnDatas datas)
{
    char *buffer = NULL;
    int code;

    code = weather_ftp_get_XYZ (sock, datas, &buffer);
    if (code == 220)
    {
        char *cmd = "USER anonymous";
        if (weather_connection_write (sock, cmd) != -1)
            weather_ftp_read_user (sock, datas);
    }
    else
        MMechostr (MSKDEBUG, "weather_ftp_read_connect : ftp error %s\n", buffer);
    free (buffer);
    return;
}


