#include "web_server.h"
#include "ws_method.h"
#include "myLog.h"
#include "mongoose.h"


static const char *s_listen_on = "http://0.0.0.0:8000";
static const char *s_update_ws = "/ws";
static const char *s_web_root = "web_root";
std::string g_web_root = "";
static struct mg_mgr mgr;

static struct mg_connection *p_conn = NULL;
static pthread_t thread_id;




void ws_send(const char *p_tx, uint16_t tx_len)
{
    if(NULL == p_conn || NULL == p_tx || 0 == tx_len)
    {
        LOG_E("ws_send arg not valid, p_conn:%p, p_tx:%p, tx_len:%d", p_conn, p_tx, tx_len);
        return;
    }
    mg_ws_send(p_conn, p_tx, tx_len, WEBSOCKET_OP_TEXT);

    // LOG_I("ws_send %d bytes: %s", tx_len, p_tx);
}

LOCAL void web_server_recv(const char *p_rx, uint16_t rx_len)
{
    if(NULL == p_rx || 0 == rx_len)
    {
        LOG_E("web_server_recv arg not valid, p_rx:%p, rx_len:%d", p_rx, rx_len);
        return;
    }

    // LOG_I("web_server_recv %d bytes: %s", rx_len, p_rx);

    ws_recv(p_rx, rx_len);
}

LOCAL void web_server_task(struct mg_connection *c, int ev, void *p_data)
{
    if(ev == MG_EV_HTTP_MSG)
    {
        struct mg_http_message *hm = (struct mg_http_message *) p_data;
        if(mg_match(hm->uri, mg_str(s_update_ws), NULL))
        {
            mg_ws_upgrade(c, hm, NULL);
            c->data[0] = 'W';
        }
        else
        {
            struct mg_http_serve_opts opts = {.root_dir = g_web_root.c_str()};
            mg_http_serve_dir(c, (mg_http_message *)p_data, &opts);
        }
    }
    else if(ev == MG_EV_WS_MSG)
    {
        p_conn = c;
        struct mg_ws_message *wm = (struct mg_ws_message *) p_data;

        printf("Got %d bytes: %s\n", (int) wm->data.len, wm->data.buf);
        
        web_server_recv(wm->data.buf, (int)wm->data.len);
    }
}


LOCAL void *web_server_run(void *arg)
{
    while(1)
    {
        mg_mgr_poll(&mgr, 500);
    }

    mg_mgr_free(&mgr);

    LOG_E("web_server_run exit");
    return NULL;
}


LOCAL void web_server_init()
{
    g_web_root = "/mnt/RTU/test/" + std::string(s_web_root);

    mg_mgr_init(&mgr);

    mg_http_listen(&mgr, s_listen_on, web_server_task, NULL);

    pthread_create(&thread_id, NULL, web_server_run, NULL);

    LOG_I("web_server_init done");
}


int app_web_server_init1(void *arg)
{
    web_server_init();
    return 0;
}

int app_web_server_init2(void *arg)
{
    return 0;
}

void *app_web_server(void *arg)
{
    if(NULL == arg)
    {
        LOG_E("app_web_server arg null");
        return NULL;
    }

    stru_app *p_app = (stru_app *)arg;

    uint32_t event;
    stru_app_msg_queue *p_mq = NULL;
    stru_msg_head *p_head = NULL;
    stru_rtx_data *p_rtx = &p_app->rtx;

    while (1)
    {
        task_event_recv(p_app->p_event, 
            EV_TIMER1 | EV_TIMER2 | EV_TIMER3,  
            TASK_EVENT_FLAG_OR | TASK_EVENT_FLAG_CLEAR,
            TASK_EVENT_WAIT_FOREVER,
            &event);

        if(event & EV_TIMER1)
        {
            ;
        }

        if(event & EV_TIMER2)
        {
            ;
        }

        if(event & EV_TIMER3)
        {
            p_app->run_cnt++;

            ws_task();
        }
    }
    


}