/*
 * app.h
 *
 *  Created on: 26.3.2014
 *      Author: Stefan
 */

#ifndef HTTP_H_
#define HTTP_H_

#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */

/* Includes ------------------------------------------------------------------*/
#include <system.h>
#include <lwip/opt.h>
#include <lwip/sys.h>
#include <lwip/api.h>

/* Public define -------------------------------------------------------------*/
#define HTTP_BUFFER_LENGTH          1024

#define HTTP_CONTENT_LENGTH_CHUNKED 0xffffffff

/* Public typedef ------------------------------------------------------------*/
typedef enum http_method_en
{
    HTTP_METHOD_UNKNOWN = -1,
    HTTP_METHOD_GET,
    HTTP_METHOD_HEAD,
    HTTP_METHOD_POST
} http_method_t;

typedef enum http_version_en
{
    HTTP_VER_UNKNOWN = -1,
    HTTP_VER_1_1,
    HTTP_VER_1_0
} http_version_t;

typedef enum http_error_en
{
    HTTP_ERR_OK = 0,
    HTTP_ERR_CONNECTION,
    HTTP_ERR_METHOD_NOT_ALLOWED,
    HTTP_ERR_BUFFER_TOO_SMALL,
    HTTP_ERR_UNKNOWN_VERSION,
    HTTP_ERR_UNKNOWN_RESPONSE_NUMBER,
    HTTP_ERR_UNKNOWN_HEADER,
    HTTP_ERR_UNKNOWN_EXTENSION
} http_err_t;

typedef enum http_header_en
{
    HTTP_HEADER_TOO_LONG = -3,
    HTTP_HEADER_EMPTY = -2,
    HTTP_HEADER_UNKNOWN = -1,

    HTPP_HEADER_HOST = 0,
    HTTP_HEADER_CONNECTION,
    HTTP_HEADER_CONTENT_LENGTH,
    HTTP_HEADER_CONTENT_TYPE,
    HTTP_HEADER_TRANSFER_ENCODING,
    HTTP_HEADER_SERVER,
    HTTP_HEADER_LOCATION
} http_header_t;

typedef enum http_transfer_encoding_en
{
    HTTP_TRANSFER_ENCODING_NORMAL = 0,
    HTTP_TRANSFER_ENCODING_CHUNKED
} http_transfer_encoding_t;

typedef struct http_request_struct
{
    http_method_t   method;
    char*           document_name;
    uint32_t        document_name_length;
    http_version_t  version;
}http_request_t;

typedef struct http_response_struct
{
    http_version_t  version;
    uint32_t        response_code;
    const char*     message;
} http_response_t;

typedef struct http_conn_info_struct
{
    struct netconn* connection;
    struct netbuf * net_buffer;
    char*           next_char;
    uint16_t        chars_left;
} http_conn_info_t;

typedef struct http_status_struct
{
    http_conn_info_t    connection;
    char                buffer[HTTP_BUFFER_LENGTH];
    uint32_t            buffered_length;
    http_transfer_encoding_t transfer_encoding;
} http_status_t;

/* Public macro --------------------------------------------------------------*/
/* Public variables ----------------------------------------------------------*/
/* Public functions ----------------------------------------------------------*/
http_err_t http_init_struct(
    http_status_t* http_info,
    struct netconn* stream
);

http_err_t http_fini_struct(
    http_status_t* http_info
);

http_err_t http_decode_request(
	http_status_t* http_info,
    http_request_t* request_info
);

http_header_t http_get_header(
    http_status_t* http_info,
    const char** value
);

http_err_t http_generate_response(
    http_status_t* http_info,
    const http_response_t* response_info
);

http_err_t http_set_header(
    http_status_t* http_info,
    http_header_t header_type,
    const char* value
);

http_err_t http_data_start(
    http_status_t* http_info,
    http_transfer_encoding_t encoding
);

http_err_t http_data_write(
    http_status_t* http_info,
    char* data,
    uint32_t length
);

http_err_t http_get_resp_msg(
    uint32_t code,
    const char** msg
);

http_err_t http_build_mmime(
    char* buffer,
    uint32_t length,
    const char* filename,
    const char* charset
);


#ifdef __cplusplus
}
#endif /* __cplusplus */


#endif /* HTTP_H_ */
