/*
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"

/* FTP */
void weather_ftp_read_connect (SOCKET sock, SConnDatas datas);



static char* weather_buffer_alloc ()
{
    char *s;

    s = malloc (sizeof (char) * 512);
    /*memset (s, '\0', 512);*/
    return s;
}

void weather_get_host (SConnDatas datas)
{
    struct hostent *sh;

    sh = gethostbyname (datas->domain);
    #if ((defined linux) || (defined __linux))
    datas->ahost = inet_ntoa (*(IN_ADDR *) sh->h_addr_list[0]);
    #else
    /*datas->ahost = malloc (sizeof (char) * strlen (sh->h_addr_list[0]));
    strcpy (datas->ahost, inet_ntoa (*(IN_ADDR *) sh->h_addr_list[0]));*/
    datas->ahost = inet_ntoa (*(IN_ADDR *)sh->h_addr_list[0]);
    #endif
    return;
}

int weather_connection_init (void)
{
    #if ((defined _WIN32) || (defined __WIN32__))
    WSADATA wsa;
    int err = WSAStartup (MAKEWORD (2, 2), &wsa);
    if (err != NO_ERROR)
    {
        MMechostr (MSKDEBUG, "weather_connection_init error : WSAStartup failed !\n");
        return 1;
    }
    #endif
    return 0;
}

void weather_connection_end (SOCKET sock)
{
    close (sock);
    #if ((defined _WIN32) || (defined __WIN32__))
    WSACleanup ();
    #endif
    return;
}

static int weather_connection_socket (SConnDatas datas)
{
    int res = 0;
    SOCKET sock;
    SOCKADDR_IN address = { 0 };
    /*ULONG fionbio = TRUE;*/

    sock = socket (AF_INET, SOCK_STREAM, 0);
    if (sock == INVALID_SOCKET)
    {
        MMechostr (MSKDEBUG, "weather_connection_socket error : socket invalid = %d", sock);
        weather_connection_end (-1);
        return -1;
    }
    /*
    #if ((defined _WIN32) || (defined __WIN32__))
    ioctlsocket (s, FIONBIO, &fionbio);
    #else
    ioctl (s, FIONBIO, &fionbio);
    #endif
    */
    address.sin_port = htons (datas->port);
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr (datas->ahost);
    if (INADDR_NONE == address.sin_addr.s_addr)
        MMechostr (MSKDEBUG, "weather_connection_socket error : address IP not converted (inet_addr)\n");

    res = connect (sock, (SOCKADDR *) &address, sizeof (address));
    if (res == SOCKET_ERROR)
    {
        MMechostr (MSKDEBUG, "weather_connection_socket error : not connected : %d, %s!\n", errno, strerror (errno));
        weather_connection_end (sock);
        return -1;
    }

    return sock;
}

int weather_connection_write (SOCKET sock, char *cmd)
{
    int res = 0;

    char buffer[512];
    snprintf (buffer, 512, "%s\r\n", cmd);

    res = send (sock, buffer, strlen (buffer), 0);
    if (res < 0)
    {
        MMechostr (MSKDEBUG, "weather_connection_write error : not sent.\nRequest : %s", cmd);
        return -1;
    }
    return 0;
}

char* weather_connection_read (SOCKET sock, SConnDatas datas)
{
    int res = 0;
    char *b = NULL;
    char z[512];

    b = weather_buffer_alloc ();
    res = recv (sock, z, sizeof (z)-1, 0);
    if (res == -1)
    {
        MMechostr (MSKDEBUG, "weather_connection_read error : not read\n");
        return NULL;
    }
    snprintf (b, 512, "%s", z);
    b[strlen (z)] = '\0';

    return b;
}


static void *weather_connection (void *u_datas)
{
    int res;
    SOCKET sock;
    SConnDatas datas = (SConnDatas) u_datas;
MMechostr (0, "weather_connection : entering\n");

    weather_get_host (datas);

    res = weather_connection_init ();
    if (res == 1)
    {
        MMechostr (MSKDEBUG, "weather_connection error : init failed\n");
        return NULL;
    }

    sock = weather_connection_socket (datas);
    if (sock == -1)
    {
        MMechostr (MSKDEBUG, "weather_connection error : socket not created\n");
        return NULL;
    }

    /*while ((weather_connection_read (sock, datas)) != -1);*/
    weather_ftp_read_connect (sock, datas);

    /*weather_connection_end (sock);*/
    return NULL;
}

int weather_connection_ended (pthread_t pt_conn)
{
    int res;

    res = pthread_join (pt_conn, NULL);
    if (res != 0)
    {
        MMechostr (MSKDEBUG, "weather_connection_ended error : code = %d\n", res);
        return 1;
    }
    return 0;
}

void weather_connection_asked (SConnDatas datas)
{
    int res = 0;
    pthread_t pt_conn;
MMechostr (0, "weather_connection_asked : entering\n");

/*weather_connection ((void *) datas);*/
    res = pthread_create (&pt_conn, NULL, weather_connection, (void *) datas);
    if (res != 0)
    {
        MMechostr (MSKDEBUG, "weather_connection_asked error : %d\n", res);
        return;
    }

    res = weather_connection_ended (pt_conn);
MMechostr (0, "weather_connection_asked : exiting\n");
    return;
}



/* A refaire proprement ! */
SConnDatas weather_connection_datas_init (const char *s_url, const char *station)
{
    SConnDatas datas;
    int len, p;

    datas = malloc (sizeof (struct SConnDatas));

    p = searchCharMem (s_url, ':');
    if (p != -1)
    {
        datas->protocol = malloc (sizeof (char) * (p+3));
        strncpy (datas->protocol, s_url, p-1);
        strncat (datas->protocol, "://", p+3);
    }
    else
        datas->protocol = "http://";

    len = strlen (datas->protocol);

    p = searchCharMem (s_url+len, ':');
    if (p != -1)
    {
        char *s;
        datas->domain = malloc (sizeof (char) * p);
        strncpy (datas->domain, s_url+len, p-1);
        len += strlen (datas->domain);
        p = searchCharMem (s_url+len, '/');
        s = malloc (sizeof (char) * p);
        strncpy (s, s_url+len, p-1);
        datas->port = atoi (s);
        len += strlen (s);
        free (s);
    }
    else
    {
        p = searchCharMem (s_url+len, '/');
        datas->domain = malloc (sizeof (char) * p);
        strncpy (datas->domain, s_url+len, p-1);
        if (0 == strcmp (datas->protocol, "ftp://"))
            datas->port = 21;
        else if (0 == strcmp (datas->protocol, "sftp://"))
            datas->port = 22;
        else
            datas->port = 80;
        len += strlen (datas->domain);
    }

    /*snprintf (datas->url, DURLMAXLEN, "GET %s HTTP/1.1\r\nHost:%s\r\nConnection: Close\r\n\r\n", s_url+len, datas->domain);
*/
    if (0 == strcmp (datas->protocol, "ftp://"))
    {
        char ftppath[128];
        char *ftpname = strrchr (s_url+len, '/')+1;
        p = searchRCharMem (s_url+len, '/');
        strncpy (ftppath, s_url+len+1, p);
        ftppath[p] = '\0';

        snprintf (datas->url, DURLMAXLEN-1, "%s", ftppath);
        snprintf (datas->city, 64-1, "%s", ftpname);
        memset (datas->buffer, 512, '\0');
        free (ftpname);
    }
    else if (0 == strcmp (datas->protocol, "http://"))
    {

    }
    else if (0 == strcmp (datas->protocol, "sftp://"))
    {

    }

/*
MMechostr (0, "weather_connection_datas_init s_url : %s\n", s_url);
MMechostr (0, "weather_connection_datas_init protocol : %s\n", datas->protocol);
MMechostr (0, "weather_connection_datas_init domain : %s\n", datas->domain);
MMechostr (0, "weather_connection_datas_init port : %d\n", datas->port);
MMechostr (0, "weather_connection_datas_init url : %s\n", datas->url);
MMechostr (0, "weather_connection_datas_init city : %s\n", datas->city);
*/
/*    s = strchr (s_url+strlen (datas->protocol)+1, ':');
    if (s == NULL)
    {
        datas->domain = strchr (s_url+strlen (datas->protocol)+1, '/');
        datas->port = 80;
        len += strlen (datas->domain);
    }
    else
    {
        strncpy (datas->domain, s, 128);
        datas->port = atoi (strchr (s_url+strlen (datas->protocol)+strlen(datas->domain)+1, '/'));
        len = len+strlen (datas->domain)+weather_number_int (datas->port)+2;
    }*/

/*
    strncpy (datas->url, s_url+len, DURLMAXLEN);
    strncpy (datas->city, station, 64);

*/


    return datas;
}
