/*
 * doc.c
 *
 *  Created on: 8.5.2014
 *      Author: Stefan
 */


/* Includes ------------------------------------------------------------------*/
#include "doc.h"
#include <stdlib.h>
#include <string.h>

#include "sensors.h"
#include "supply.h"

/* Private define ------------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static char* doc_connection[] =
{
    "Close",
    "Keep-Alive"
};

static char doc_server_signature[] = "Meteo by Stefan Misik";

static const char* doc_rests[] =
{
    "current",
    "supply"
};

/* Public variables ----------------------------------------------------------*/
extern char* www_names[];
extern unsigned char* www_contents[];
extern unsigned int www_file_sizes[];
extern unsigned int www_count;

/* Private functions ---------------------------------------------------------*/
static void doc_read_headers(
    httpd_srv_data_t* srv_info
)
{
    http_header_t header_type;
    const char* header_val;

    header_type = http_get_header(&(srv_info->http_status), &header_val);
    while(header_type >= HTTP_HEADER_UNKNOWN)
    {
        if(header_type == HTTP_HEADER_CONNECTION)
        {
            if(0 == stricmp(doc_connection[0], header_val))
            {
                srv_info->connection_close = TRUE;
            }
        }

        header_type = http_get_header(&(srv_info->http_status), &header_val);
    }

}

/* Public functions ----------------------------------------------------------*/

#define DOC_BUFFER_LENGTH 128

bool_t doc_send_file(
    httpd_srv_data_t* srv_info,
    const char* name
)
{
    http_response_t http_response;
    char buffer[DOC_BUFFER_LENGTH];
    uint32_t file_id;
    int tmp;


    for(file_id = 0; file_id < www_count; file_id ++)
    {
        if(0 == strcmp(name, www_names[file_id]))
        {
            break;
        }
    }

    if(file_id == www_count)
    {
        return FALSE;
    }

    doc_read_headers(srv_info);

    /* Send response */
    http_response.message = NULL;
    http_response.response_code = 200;
    http_response.version = HTTP_VER_1_1;
    http_generate_response(&(srv_info->http_status), &http_response);

    /* Send Server Signature */
    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_SERVER,
        doc_server_signature);

    /* Mime Type */
    if (HTTP_ERR_OK != http_build_mmime(buffer, DOC_BUFFER_LENGTH,
        www_names[file_id], "Windows-1250")
    )
    {
        strcpy(buffer, "application/octet-stream");
    }
    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_CONTENT_TYPE,
        buffer);

    /* Try to send content length header */
    tmp = snprintf(buffer, DOC_BUFFER_LENGTH, "%u", www_file_sizes[file_id]);
    if(tmp > 0 && tmp < DOC_BUFFER_LENGTH)
    {
        http_set_header(
            &(srv_info->http_status),
            HTTP_HEADER_CONTENT_LENGTH,
            buffer);
    }
    else
    {
        srv_info->connection_close = TRUE;
    }

    /* Connection Status */
    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_CONNECTION,
        doc_connection[(srv_info->connection_close) ? 0 : 1]);

    /* Start Data transfer */
    http_data_start(
        &(srv_info->http_status),
        HTTP_TRANSFER_ENCODING_NORMAL);

    /* Write data */
    netconn_write(srv_info->current_connection, www_contents[file_id],
        www_file_sizes[file_id], NETCONN_NOCOPY);


    return TRUE;
}

bool_t doc_send_rest(
    httpd_srv_data_t* srv_info,
    const char* name
)
{
    http_response_t http_response;
    char buffer[DOC_BUFFER_LENGTH];
    uint32_t rest_id;


    for(rest_id = 0; rest_id < (sizeof(doc_rests) / sizeof(char*)); rest_id ++)
    {
        if(0 == strcmp(name, doc_rests[rest_id]))
        {
            break;
        }
    }

    if(rest_id == (sizeof(doc_rests) / sizeof(char*)))
    {
        return FALSE;
    }

    doc_read_headers(srv_info);

    /* Send response */
    http_response.message = NULL;
    http_response.response_code = 200;
    http_response.version = HTTP_VER_1_1;
    http_generate_response(&(srv_info->http_status), &http_response);

    /* Send Server Signature */
    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_SERVER,
        doc_server_signature);

    /* Mime Type */
    if (HTTP_ERR_OK != http_build_mmime(buffer, DOC_BUFFER_LENGTH,
        ".json", "Windows-1250")
    )
    {
        strcpy(buffer, "application/octet-stream");
    }
    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_CONTENT_TYPE,
        buffer);


    /* Chunked encoding */
    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_TRANSFER_ENCODING,
        "Chunked");

    /* Connection Status */
    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_CONNECTION,
        doc_connection[(srv_info->connection_close) ? 0 : 1]);

    /* Start Data transfer */
    http_data_start(
        &(srv_info->http_status),
        HTTP_TRANSFER_ENCODING_CHUNKED);

    /* Write data */

    switch(rest_id)
    {
    case 0:
    {
        char* buffer = malloc(1024);
        if(NULL != buffer)
        {
            uint32_t length;
            float bat;
            sensors_measurement_t meas;

            if(FALSE == supply_battery_status(&bat))
            {
                bat = -1.0f;
            }

            sensors_get_current_measurement(&meas);

            length = snprintf(buffer, 1024,
                "{\"bat\":%i,\"ext_pwr\":%u,\"chrg\":%u,\"hum\":%u,\"press\":%u,\"rain\":%u,\"temp\":%u,\"wind_dir\":%u,\"wind_spd\":%u}",
                (int)bat,
                (unsigned int)supply_ext_pwr_state(),
                (unsigned int)supply_charge_state(),
                (unsigned int)meas.humidity,
                (unsigned int)meas.press,
                (unsigned int)meas.rain,
                (unsigned int)(meas.temp * 10),
                (unsigned int)meas.wind_dir,
                (unsigned int)(meas.wind_spd * 100));

            http_data_write(
                &(srv_info->http_status),
                buffer, length);

            free(buffer);
        }

        break;
    }
    case 1:
    {
        char* buffer = malloc(1024);
        if(NULL != buffer)
        {
            uint32_t length;
            float bat;

            if(FALSE == supply_battery_status(&bat))
            {
                bat = -1.0f;
            }

            length = snprintf(buffer, 1024,
                "{\"bat\":%i,\"ext_pwr\":%u,\"chrg\":%u}",
                (int)bat,
                (unsigned int)supply_ext_pwr_state(),
                (unsigned int)supply_charge_state());

            http_data_write(
                &(srv_info->http_status),
                buffer, length);

            free(buffer);
        }

        break;
    }

    }

    http_data_write(
        &(srv_info->http_status),
        NULL, 0);

    return TRUE;



}


void doc_send_error_page(
    httpd_srv_data_t* srv_info,
    uint32_t err_code
)
{
    const char* tmp;
    http_response_t http_response;
    uint32_t length = 0;
    char buffer[DOC_BUFFER_LENGTH];
    char length_string[16];


    if(HTTP_ERR_OK == http_get_resp_msg(err_code, &tmp))
    {
        length = snprintf(
            buffer,
            1024,
            "<h1>%u %s</h1><br /> Požadovaný súbor: \"%s\"",
            (unsigned int) err_code,
            tmp,
            srv_info->url);
    }

    doc_read_headers(srv_info);

    /* Send response */
    http_response.message = NULL;
    http_response.response_code = err_code;
    http_response.version = HTTP_VER_1_1;
    http_generate_response(&(srv_info->http_status), &http_response);

    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_SERVER,
        "Meteo by Stefan Misik");

    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_CONNECTION,
        "Close");

    srv_info->connection_close = TRUE;


    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_CONTENT_TYPE,
        "text/html; charset=Windows-1250");

    snprintf(length_string, 16, "%u", (unsigned int)length);

    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_CONTENT_LENGTH,
        length_string);

     http_data_start(
        &(srv_info->http_status),
        HTTP_TRANSFER_ENCODING_NORMAL);

    http_data_write(
        &(srv_info->http_status),
        buffer,
        length);
}

void doc_redirect(
    httpd_srv_data_t* srv_info,
    char* page
)
{
    http_response_t http_response;
    uint32_t length = 0;
    char buffer[DOC_BUFFER_LENGTH];
    char length_string[16];
    const char* tmp;

    doc_read_headers(srv_info);

    if(HTTP_ERR_OK == http_get_resp_msg(301, &tmp))
    {
        length = snprintf(
            buffer,
            1024,
            "<h1>%u %s</h1><br />Pokračujte <a href=\"%s\">TU</a>.",
            (unsigned int) 301,
            tmp,
            page);
    }

    /* Send response */
    http_response.message = NULL;
    http_response.response_code = 301;
    http_response.version = HTTP_VER_1_1;
    http_generate_response(&(srv_info->http_status), &http_response);

    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_SERVER,
        "Meteo by Stefan Misik");

    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_LOCATION,
        page);


    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_CONNECTION,
        "Keep-Alive");

    srv_info->connection_close = FALSE;


    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_CONTENT_TYPE,
        "text/html; charset=Windows-1250");

    snprintf(length_string, 16, "%u", (unsigned int)length);

    http_set_header(
        &(srv_info->http_status),
        HTTP_HEADER_CONTENT_LENGTH,
        length_string);

     http_data_start(
        &(srv_info->http_status),
        HTTP_TRANSFER_ENCODING_NORMAL);

    http_data_write(
        &(srv_info->http_status),
        buffer,
        length);
}
