#include <logger.h>
#include <cJSON.h>
#include <mongoose.h>
#include <macros.h>
#include <endpoint.h>

void
endpoint_func_index(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response)
{
    (void)args;
    (void)hm;
    (void)nc;
    (void)response;

    response->status_code = 0;

    mg_serve_http(nc, hm, global_config->http_server_opts);
}

void
endpoint_func_not_found(struct mg_connection *nc, struct http_message *hm, endpoint_args_t *args, endpoint_response_t *response)
{
    (void)args;
    (void)hm;
    (void)nc;
    
    if(access(global_config->not_found_file, R_OK) != -1)
    {
        struct mg_str mime_type = mg_mk_str(global_config->not_found_file_type);
        response->status_code = 0;
        mg_http_serve_file(nc, hm, global_config->not_found_file, mime_type, mg_mk_str(""));
    }
    else
    {
        LOGGER_DEBUG("404 file not found\n");

        endpoint_response_free_content(response);

        response->status_code = 404;
        response->content_type = global_config->not_found_content_type;
        response->content_length = strlen(global_config->not_found_content);
        response->content = global_config->not_found_content;
        response->alloced_content = false;
    }

}

void
endpoint_response_msg(endpoint_response_t *response, int status_code, const char *content, int content_length)
{
    endpoint_response_free_content(response);

    cJSON *json;

    json = cJSON_CreateObject();
    cJSON *json_msg;

    if(content_length)
    {
        json_msg = cJSON_CreateStringReference(content);
    }
    else
    {
        json_msg = cJSON_CreateString(content);
    }
    if(json_msg == NULL)
    {
        endpoint_response_text(response, status_code, content, content_length);
        return;
    }
    cJSON_AddItemToObject(json, "msg", json_msg);

    endpoint_response_json(response, status_code, json);

    cJSON_Delete(json);
}

void
endpoint_response_text(endpoint_response_t *response, int status_code, const char *content, int content_length)
{
    endpoint_response_free_content(response);
    if(content == NULL)
    {
        content = "";
        content_length = 0;
    }

    response->status_code = status_code;
    response->content_type = "text/plain";
    if(content_length)
    {
        response->content_length = content_length;
        response->alloced_content = false;
        response->content = (char*)content;
    }
    else
    {
        response->content_length = strlen(content);
        response->alloced_content = true;

        response->content = malloc(sizeof(char) * (response->content_length + 1));
        strcpy(response->content, content);
        response->content[response->content_length] = '\0';
    }
}

void
endpoint_response_json(endpoint_response_t *response, int status_code, const cJSON *json_root)
{
    endpoint_response_free_content(response);
    if(json_root != NULL)
    {
        char *json_str = cJSON_Print(json_root);
        if (json_str != NULL)
        {
            response->status_code = status_code;
            response->content_type = "application/json";
            response->content_length = strlen(json_str);
            response->content = json_str;
            response->alloced_content = true;

            return;
        }
    }

    M_RESPONSE_MSG(LOGGER_ERR, response, 500, "failed to print json");
}

void
endpoint_response_free_content(endpoint_response_t *response)
{
    if(response->alloced_content)
    {
        free(response->content);
        response->content = NULL;
        response->alloced_content = false;
    }
}