/*
 * 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"
            "  <capabilities>websocket</capabilities>\r\n",
            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;
}

void DIAL_start(DIALServer *ds) {
    ds->ctx = mg_start(&request_handler, ds, DIAL_PORT);
}

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;
}

