/*
 * Copyright (c) 2014 Netflix, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY NETFLIX, INC. AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NETFLIX OR CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "dial_data.h"
#include "dial_server.h"

#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>

#include "mongoose.h"
#include "url_lib.h"

// TODO: Partners should define this port
#define DIAL_PORT (56789)
#define DIAL_DATA_SIZE (8*1024)

static const char *gLocalhost = "127.0.0.1";

struct DIALApp_ {
    struct DIALApp_ *next;
    struct DIALAppCallbacks callbacks;
    struct DIALData_ *dial_data;
    void *callback_data;
    DIAL_run_t run_id;
    DIALStatus state;
    char *name;
    char payload[DIAL_MAX_PAYLOAD];
    int useAdditionalData;
    char corsAllowedOrigin[256];

};

typedef struct DIALApp_ DIALApp;

struct DIALServer_ {
    struct mg_context *ctx;
    struct DIALApp_ *apps;
    pthread_mutex_t mux;
};

static void ds_lock(DIALServer *ds) {
    pthread_mutex_lock(&ds->mux);
}

static void ds_unlock(DIALServer *ds) {
    pthread_mutex_unlock(&ds->mux);
}

// finds an app and returns a pointer to the previous element's next pointer
// if not found, return a pointer to the last element's next pointer
static DIALApp **find_app(DIALServer *ds, const char *app_name) {
    DIALApp *app;
    DIALApp **ret = &ds->apps;

    for (app = ds->apps; app != NULL; ret = &app->next, app = app->next) {
        if (!strcmp(app_name, app->name)) {
            break;
        }
    }
    return ret;
}

static void url_decode_xml_encode(char *dst, char *src, size_t src_size) {
    char *url_decoded_key = (char *) malloc(src_size + 1);
    urldecode(url_decoded_key, src, src_size);
    xmlencode(dst, url_decoded_key, 2 * src_size);
    free(url_decoded_key);
}

/*
 * A bad payload is defined to be an unprintable character or a
 * non-ascii character.
 */
static int isBadPayload(const char* pPayload, int numBytes) {
    int i = 0;
    fprintf( stderr, "Payload: checking %d bytes\n", numBytes);
    for (; i < numBytes; i++) {
        // High order bit should not be set
        // 0x7F is DEL (non-printable)
        // Anything under 32 is non-printable
        if (((pPayload[i] & 0x80) == 0x80) || (pPayload[i] == 0x7F)
                || (pPayload[i] <= 0x1F))
            return 1;
    }
    return 0;
}

static void handle_app_start(struct mg_connection *conn,
                             const struct mg_request_info *request_info,
                             const char *app_name,
                             const char *origin_header) {
    char additional_data_param[256] = {0, };
    char body[DIAL_MAX_PAYLOAD] = {0, };
    DIALApp *app;
    DIALServer *ds = request_info->user_data;
    int body_size;

    ds_lock(ds);
    app = *find_app(ds, app_name);
    if (!app) {
        mg_send_http_error(conn, 404, "Not Found", "Not Found");
    } else {
        body_size = mg_read(conn, body, sizeof(body));
        // NUL-terminate it just in case
        if (body_size > DIAL_MAX_PAYLOAD) {
            mg_send_http_error(conn, 413, "413 Request Entity Too Large",
                               "413 Request Entity Too Large");
        } else if (isBadPayload(body, body_size)) {
            mg_send_http_error(conn, 400, "400 Bad Request", "400 Bad Request");
        } else {
            char laddr[INET6_ADDRSTRLEN];
            const struct sockaddr_in *addr =
                    (struct sockaddr_in *) &request_info->local_addr;
            inet_ntop(addr->sin_family, &addr->sin_addr, laddr, sizeof(laddr));
            in_port_t dial_port = DIAL_get_port(ds);

            if (app->useAdditionalData) {
                // Construct additionalDataUrl=http://host:port/apps/app_name/dial_data
                snprintf(additional_data_param, sizeof(additional_data_param),
                        "%sadditionalDataUrl=http%%3A%%2F%%2Flocalhost%%3A%d%%2Fapps%%2F%s%%2Fdial_data%%3F",
                        (body_size != 0) ? "&" : "",
                        dial_port, app_name);
                if ((body_size + strlen(additional_data_param)) < DIAL_MAX_PAYLOAD) {
                    strcat(body, additional_data_param);
                    body_size = strlen(body);
                } else {
                    fprintf(stderr, "payload too small for additional data\n");
                }
            }
            fprintf(stderr, "Starting the app with params %s\n", body);
            app->state = app->callbacks.start_cb(ds, app_name, body, body_size,
                                                 &app->run_id,
                                                 app->callback_data);
            if (app->state == kDIALStatusRunning) {
                mg_printf(
                        conn,
                        "HTTP/1.1 201 Created\r\n"
                        "Content-Type: text/plain\r\n"
                        "Location: http://%s:%d/apps/%s/run\r\n"
                        "Access-Control-Allow-Origin: %s\r\n"
                        "\r\n",
                        laddr, dial_port, app_name, origin_header);
                // copy the payload into the application struct
                memset(app->payload, 0, DIAL_MAX_PAYLOAD);
                if (body_size<=DIAL_MAX_PAYLOAD) {
                    memcpy(app->payload, body, body_size);
                } else {
                    fprintf(stderr, "payload too small for body of %d bytes\n", body_size);
                }
            } else {
                mg_send_http_error(conn, 503, "Service Unavailable",
                                   "Service Unavailable");
            }
        }
    }
    ds_unlock(ds);
}

static void handle_app_status(struct mg_connection *conn,
                              const struct mg_request_info *request_info,
                              const char *app_name,
                              const char *origin_header) {
    DIALApp *app;
    int canStop = 0;
    DIALServer *ds = request_info->user_data;

    ds_lock(ds);
    app = *find_app(ds, app_name);
    if (!app) {
        mg_send_http_error(conn, 404, "Not Found", "Not Found");
        ds_unlock(ds);
        return;
    }

    char dial_data[DIAL_DATA_SIZE] = {0,};
    char *end = dial_data + DIAL_DATA_SIZE;
    char *p = dial_data;

    for (DIALData* first = app->dial_data; first != NULL; first = first->next) {
        p = smartstrcat(p, "    <", end - p);
        size_t key_length = strlen(first->key);
        char *encoded_key = (char *) malloc(2 * key_length + 1);
        url_decode_xml_encode(encoded_key, first->key, key_length);

        size_t value_length = strlen(first->value);
        char *encoded_value = (char *) malloc(2 * value_length + 1);
        url_decode_xml_encode(encoded_value, first->value, value_length);

        p = smartstrcat(p, encoded_key, end - p);
        p = smartstrcat(p, ">", end - p);
        p = smartstrcat(p, encoded_value, end - p);
        p = smartstrcat(p, "</", end - p);
        p = smartstrcat(p, encoded_key, end - p);
        p = smartstrcat(p, ">", end - p);
        free(encoded_key);
        free(encoded_value);
    }
    app->state = app->callbacks.status_cb(ds, app_name, app->run_id, &canStop,
                                          app->callback_data);
    mg_printf(
            conn,
            "HTTP/1.1 200 OK\r\n"
            "Content-Type: application/xml\r\n"
            "Access-Control-Allow-Origin: %s\r\n"
            "\r\n"
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
            "<service xmlns=\"urn:dial-multiscreen-org:schemas:dial\" dialVer=%s>\r\n"
            "  <name>%s</name>\r\n"
            "  <options allowStop=\"%s\"/>\r\n"
            "  <state>%s</state>\r\n"
            "%s",
            origin_header,
            DIAL_VERSION,
            app->name,
            canStop ? "true" : "false",
            app->state ? "running" : "stopped",
            app->state == kDIALStatusStopped ?
                    "" : "  <link rel=\"run\" href=\"run\"/>\r\n");
    if (strlen(dial_data)>0) {
        mg_printf(
            conn,
            "  <additionalData>\r\n"
            "%s"
            "\r\n  </additionalData>\r\n",
            dial_data);
    }
    if (app->callbacks.service_data_cb != NULL) {
        struct CastServiceData serviceData = app->callbacks.service_data_cb(ds, app_name, app->run_id, app->callback_data);
        mg_printf(conn,
                  "  <servicedata xmlns=\"urn:chrome.google.com:cast\">\r\n"
                  "    <connectionSvcURL>http://%s:%d%s</connectionSvcURL>\r\n"
                  "    <protocols>\r\n"
                  "      <protocol>%s</protocol>\r\n"
                  "    </protocols>\r\n"
                  "  </servicedata>\r\n",
                  serviceData.connection_svc_host,
                  serviceData.connection_svc_port,
                  serviceData.connection_svc_path,
                  serviceData.protocol);
    }
    if (app->callbacks.activity_status_cb != NULL) {
        struct CastActivityStatus activityStatus = app->callbacks.activity_status_cb(ds, app_name, app->run_id, app->callback_data);
        mg_printf(conn,
                  "  <activity-status xmlns=\"urn:chrome.google.com:cast\">\r\n"
                  "    <description>%s</description>\r\n"
                  "  </activity-status>\r\n", activityStatus.description);
    }
    mg_printf(conn, "</service>\r\n");
    ds_unlock(ds);
}

static void handle_app_stop(struct mg_connection *conn,
                            const struct mg_request_info *request_info,
                            const char *app_name,
                            const char *origin_header) {
    DIALApp *app;
    DIALServer *ds = request_info->user_data;
    int canStop = 0;

    ds_lock(ds);
    app = *find_app(ds, app_name);

    // update the application state
    if (app) {
        app->state = app->callbacks.status_cb(ds, app_name, app->run_id,
                                              &canStop, app->callback_data);
    }

    if (!app || app->state != kDIALStatusRunning) {
        mg_send_http_error(conn, 404, "Not Found", "Not Found");
    } else {
        app->callbacks.stop_cb(ds, app_name, app->run_id, app->callback_data);
        app->state = kDIALStatusStopped;
        mg_printf(conn, "HTTP/1.1 200 OK\r\n"
                  "Content-Type: text/plain\r\n"
                  "Access-Control-Allow-Origin: %s\r\n"
                  "\r\n",
                  origin_header);
    }
    ds_unlock(ds);
}

static void handle_dial_data(struct mg_connection *conn,
                             const struct mg_request_info *request_info,
                             const char *app_name,
                             const char *origin_header,
                             int use_payload) {
    char body[DIAL_DATA_MAX_PAYLOAD + 2] = {0, };

    DIALApp *app;
    DIALServer *ds = request_info->user_data;

    ds_lock(ds);
    app = *find_app(ds, app_name);
    if (!app) {
        mg_send_http_error(conn, 404, "Not Found", "Not Found");
        ds_unlock(ds);
        return;
    }
    int nread;
    if (!use_payload) {
        if (request_info->query_string) {
            strncpy(body, request_info->query_string, DIAL_DATA_MAX_PAYLOAD);
            nread = strlen(body);
        } else {
          nread = 0;
        }
    } else {
        nread = mg_read(conn, body, DIAL_DATA_MAX_PAYLOAD);
        body[nread] = '\0';
    }
    if (nread > DIAL_DATA_MAX_PAYLOAD) {
        mg_send_http_error(conn, 413, "413 Request Entity Too Large",
                           "413 Request Entity Too Large");
        ds_unlock(ds);
        return;
    }

    if (isBadPayload(body, nread)) {
        mg_send_http_error(conn, 400, "400 Bad Request", "400 Bad Request");
        ds_unlock(ds);
        return;
    }

    app->dial_data = parse_params(body);
    store_dial_data(app->name, app->dial_data);

    mg_printf(conn, "HTTP/1.1 200 OK\r\n"
              "Access-Control-Allow-Origin: %s\r\n"
              "\r\n",
              origin_header);

    ds_unlock(ds);
}

// Add logic to test if we should drop DIAL requests
#define SAGE_PROPERTIES_PATH "/rw/sage/SageClient.properties"
#define DIAL_DISABLED_PROPERTY "allow_dial=false"

int dial_allowed() {
    char property[1024];
    FILE *sageProperties;
    if (!(sageProperties = fopen(SAGE_PROPERTIES_PATH,"r"))) {
        return 1;
    }
    while (!feof(sageProperties)) {
        fgets(property, sizeof(property), sageProperties);
        if (strncmp(property, DIAL_DISABLED_PROPERTY, strlen(DIAL_DISABLED_PROPERTY))==0) {
            fclose(sageProperties);
            return 0;
        }
    }
    fclose(sageProperties);
    return 1;
}

static int ends_with(const char *str, const char *suffix) {
    if (!str || !suffix)
        return 0;
    size_t lenstr = strlen(str);
    size_t lensuffix = strlen(suffix);
    if (lensuffix > lenstr)
        return 0;
    return strncmp(str + lenstr - lensuffix, suffix, lensuffix) == 0;
}


// str contains a white space separated list of strings (only supports SPACE  characters for now)
static int ends_with_in_list (const char *str, const char *list) {
    if (!str || !list)
        return 0;
    
    const char * scanPointer=list;
    const char * spacePointer;
    unsigned int substringSize = 257;
    char *substring = (char *)malloc(substringSize);
    if (!substring){
        return 0;
    }
    while ( (spacePointer =strchr(scanPointer, ' ')) != NULL) {
    	int copyLength = spacePointer - scanPointer;      
      
      // protect against buffer overflow
      if (copyLength>=substringSize){
          substringSize=copyLength+1;
          free(substring);
          substring=(char *)malloc(substringSize);
          if (!substring){
              return 0;
          }
      }

    	memcpy(substring, scanPointer, copyLength);
    	substring[copyLength] = '\0';
    	//printf("found %s \n", substring);
    	if (ends_with(str, substring)) {
          free(substring);
          return 1;
    	}
    	scanPointer = scanPointer + copyLength + 1; // assumption: only 1 character
    }
    free(substring);
    return ends_with(str, scanPointer);
}

static int should_check_for_origin( char * origin ) {
    const char * const CHECK_PROTOS[] = { "http:", "https:", "file:" };
    for (int i = 0; i < 3; ++i) {
        if (!strncmp(origin, CHECK_PROTOS[i], strlen(CHECK_PROTOS[i]) - 1)) {
            return 1;
        }
    }
    return 0;
}

static int is_allowed_origin(DIALServer* ds, char * origin, const char * app_name) {
    if (!origin || strlen(origin)==0 || !should_check_for_origin(origin)) {
        return 1;
    }

    ds_lock(ds);
    DIALApp *app;
    int result = 0;
    for (app = ds->apps; app != NULL; app = app->next) {
    	if (!strcmp(app->name, app_name)) {
            if (!app->corsAllowedOrigin[0] ||
                ends_with_in_list(origin, app->corsAllowedOrigin)) {
                result = 1;
                break;
            }
        }
    }
    ds_unlock(ds);

    return result;
}

#define APPS_URI "/apps/"
#define RUN_URI "/run"

static void *options_response(DIALServer *ds, struct mg_connection *conn, char *host_header, char *origin_header, const char* app_name, const char* methods)
{    
    if (host_header && is_allowed_origin(ds, origin_header, app_name)) {
        mg_printf(
                  conn,
                  "HTTP/1.1 204 No Content\r\n"
                  "Access-Control-Allow-Methods: %s\r\n"
                  "Access-Control-Max-Age: 86400\r\n"
                  "Access-Control-Allow-Origin: %s\r\n"
                  "Content-Length: 0"
                  "\r\n",
                  methods,
                  origin_header);
        return "done";
    }
    mg_send_http_error(conn, 403, "Forbidden", "Forbidden");
    return "done";   
}

static void *request_handler(enum mg_event event, struct mg_connection *conn,
                             const struct mg_request_info *request_info) {
    DIALServer *ds = request_info->user_data;

    fprintf(stderr, "Received request %s\n", request_info->uri);
    char *host_header = {0,};
    char *origin_header = {0,};
    for (int i = 0; i < request_info->num_headers; ++i) {
        if (!strcmp(request_info->http_headers[i].name, "Host")) {
            host_header = request_info->http_headers[i].value;
        } else if (!strcmp(request_info->http_headers[i].name,
                          "Origin")) {
            origin_header = request_info->http_headers[i].value;
        }
    }
    fprintf(stderr, "Origin %s, Host: %s\n", origin_header, host_header);
    if (event == MG_NEW_REQUEST) {
        // If DIAL is disabled, drop the request
        if (!dial_allowed())
          return "done";
        // URL ends with run
        if (!strncmp(request_info->uri + strlen(request_info->uri) - 4, RUN_URI,
                     strlen(RUN_URI))) {
            char app_name[256] = {0, };  // assuming the application name is not over 256 chars.
            strncpy(app_name, request_info->uri + strlen(APPS_URI),
                    ((strlen(request_info->uri) - 4) - (sizeof(APPS_URI) - 1)));

            if (!strcmp(request_info->request_method, "OPTIONS")) {
                return options_response(ds, conn, host_header, origin_header, app_name, "DELETE, OPTIONS");
            }

            // DELETE non-empty app name
            if (app_name[0] != '\0'
                    && !strcmp(request_info->request_method, "DELETE")) {
                if (host_header && is_allowed_origin(ds, origin_header, app_name)) {
                    handle_app_stop(conn, request_info, app_name, origin_header);
                } else {
                    mg_send_http_error(conn, 403, "Forbidden", "Forbidden");
                    return "done";
                }
            } else {
                mg_send_http_error(conn, 501, "Not Implemented",
                                   "Not Implemented");
            }
        }
        // URI starts with "/apps/" and is followed by an app name
        else if (!strncmp(request_info->uri, APPS_URI, sizeof(APPS_URI) - 1)
                && !strchr(request_info->uri + strlen(APPS_URI), '/')) {
            const char *app_name;
            app_name = request_info->uri + sizeof(APPS_URI) - 1;

            if (!strcmp(request_info->request_method, "OPTIONS")) {
                return options_response(ds, conn, host_header, origin_header, app_name, "GET, POST, OPTIONS");
            }

            // start app
            if (!strcmp(request_info->request_method, "POST")) {
                if (host_header && is_allowed_origin(ds, origin_header, app_name)) {
                    handle_app_start(conn, request_info, app_name, origin_header);
                } else {
                    mg_send_http_error(conn, 403, "Forbidden", "Forbidden");
                    return "done";
                }
            // get app status
            } else if (!strcmp(request_info->request_method, "GET")) {
                handle_app_status(conn, request_info, app_name, origin_header);
            } else {
                mg_send_http_error(conn, 501, "Not Implemented",
                                   "Not Implemented");
            }
        // URI is of the form */app_name/dial_data
        } else if (strstr(request_info->uri, DIAL_DATA_URI)) {
            char laddr[INET6_ADDRSTRLEN];
            const struct sockaddr_in *addr =
                    (struct sockaddr_in *) &request_info->remote_addr;
            inet_ntop(addr->sin_family, &addr->sin_addr, laddr, sizeof(laddr));
            if ( !strncmp(laddr, gLocalhost, strlen(gLocalhost)) ) {
                char *app_name = parse_app_name(request_info->uri);

                if (!strcmp(request_info->request_method, "OPTIONS")) {
                    void *ret = options_response(ds, conn, host_header, origin_header, app_name, "POST, OPTIONS");
                    free(app_name);
                    return ret;
                }

                int use_payload =
                    strcmp(request_info->request_method, "POST") ? 0 : 1;
                handle_dial_data(conn, request_info, app_name, origin_header,
                                 use_payload);

                free(app_name);
            } else {
                // If the request is not from local host, return an error
                mg_send_http_error(conn, 403, "Forbidden", "Forbidden");
            }
        } else {
            mg_send_http_error(conn, 404, "Not Found", "Not Found");
        }
        return "done";
    } else if (event == MG_EVENT_LOG) {
        fprintf( stderr, "MG: %s\n", request_info->log_message);
        return "done";
    }
    return NULL;
}

DIALServer *DIAL_create() {
    DIALServer *ds = calloc(1, sizeof(DIALServer));
    pthread_mutex_init(&ds->mux, NULL);
    return ds;
}

int DIAL_start(DIALServer *ds) {
    ds->ctx = mg_start(&request_handler, ds, DIAL_PORT);
    return (ds->ctx == NULL) ? 1 : 0;
}

void DIAL_stop(DIALServer *ds) {
    mg_stop(ds->ctx);
    pthread_mutex_destroy(&ds->mux);
}

in_port_t DIAL_get_port(DIALServer *ds) {
    struct sockaddr sa;
    socklen_t len = sizeof(sa);
    if (!mg_get_listen_addr(ds->ctx, &sa, &len)) {
        return 0;
    }
    return ntohs(((struct sockaddr_in *) &sa)->sin_port);
}

int DIAL_register_app(DIALServer *ds, const char *app_name,
                      struct DIALAppCallbacks *callbacks, void *user_data,
                      int useAdditionalData,
                      const char* corsAllowedOrigin) {
    DIALApp **ptr, *app;
    int ret;

    ds_lock(ds);
    ptr = find_app(ds, app_name);
    if (*ptr != NULL) {  // app already registered
        ds_unlock(ds);
        ret = 0;
    } else {
        app = malloc(sizeof(DIALApp));
        app->callbacks = *callbacks;
        app->name = strdup(app_name);
        app->next = *ptr;
        app->state = kDIALStatusStopped;
        app->callback_data = user_data;
        app->dial_data = retrieve_dial_data(app->name);
        app->useAdditionalData = useAdditionalData;
        app->corsAllowedOrigin[0] = '\0';
        if (corsAllowedOrigin &&
            strlen(corsAllowedOrigin) < sizeof(app->corsAllowedOrigin)) {
          strcpy(app->corsAllowedOrigin, corsAllowedOrigin);
        }
        *ptr = app;
        ret = 1;
    }
    ds_unlock(ds);
    return ret;
}

int DIAL_unregister_app(DIALServer *ds, const char *app_name) {
    DIALApp **ptr, *app;
    int ret;

    ds_lock(ds);
    ptr = find_app(ds, app_name);
    if (*ptr == NULL) {  // no such app
        ret = 0;
    } else {
        app = *ptr;
        *ptr = app->next;
        free(app->name);
        free(app);
        ret = 1;
    }

    ds_unlock(ds);
    return ret;
}

const char * DIAL_get_payload(DIALServer *ds, const char *app_name) {
    const char * pPayload = NULL;
    DIALApp **ptr, *app;

    // NOTE: Don't grab the mutex as we are calling this function from
    // inside the application callback which already has the lock.
    //ds_lock(ds);
    ptr = find_app(ds, app_name);
    if (*ptr != NULL) {
        app = *ptr;
        pPayload = app->payload;
    }
    //ds_unlock(ds);
    return pPayload;
}

