/*
 * Copyright (c) 2012 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_server.h"

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

#include "mongoose.h"

// TODO: Partners should define this port
#define DIAL_PORT (56789)

struct DIALApp_ {
    struct DIALApp_ *next;
    struct DIALAppCallbacks callbacks;
    void *callback_data;
    DIAL_run_t run_id;
    DIALStatus state;
    char *name;
    char payload[DIAL_MAX_PAYLOAD];
};

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

/*
 * 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, "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) {
    char body[DIAL_MAX_PAYLOAD+2] = {0,};
    DIALApp *app;
    DIALServer *ds = request_info->user_data;
    int nread;
  
    ds_lock(ds);
    app = *find_app(ds, app_name);
    if (!app) {
        mg_send_http_error(conn, 404, "Not Found", "Not Found");
    } else {
        nread = mg_read(conn, body, sizeof(body));
        // NUL-terminate it just in case
        if( nread > DIAL_MAX_PAYLOAD ) {
            mg_send_http_error(conn, 413, "413 Request Entity Too Large",
                             "413 Request Entity Too Large");
        }
        else if( isBadPayload( body, nread ) ){
            mg_send_http_error(conn, 400, "400 Bad Request", "400 Bad Request");
        }
        else {
            app->state = app->callbacks.start_cb(ds, app_name, body, nread,
                                                 &app->run_id, app->callback_data);
            if (app->state == kDIALStatusRunning) {
                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));
                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"
                                "\r\n", laddr, DIAL_get_port(ds), app_name);
                // copy the payload into the application struct
                memset( app->payload, 0, DIAL_MAX_PAYLOAD );
                memcpy( app->payload, body, nread );
            } 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) {
    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");
    } else {
        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"
                      "\r\n"
                      "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"
                      "<service xmlns=\"urn:dial-multiscreen-org:schemas:dial\">\r\n"
                      "  <name>%s</name>\r\n"
                      "  <options allowStop=\"%s\"/>\r\n"
                      "  <state>%s</state>\r\n",
                      app->name, canStop ? "true":"false",
                      app->state ? "running" : "stopped");
        if (app->state != kDIALStatusStopped) {
            mg_printf(conn,
                      "  <link rel=\"run\" href=\"run\"/>\r\n");
        }
        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"
                      "  </servicedata>\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) {
    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"
                        "\r\n");
    }
    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;
}

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

static void *request_handler(enum mg_event event,
                             struct mg_connection *conn,
                             const struct mg_request_info *request_info) {
    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)) );
      
            // DELETE non-empty app name
            if (app_name[0] != '\0' &&
                !strcmp(request_info->request_method, "DELETE")) {
                handle_app_stop(conn, request_info, app_name);
            } else {
                mg_send_http_error(conn, 501, "Not Implemented", "Not Implemented");
            }
        }
        // URI starts with "/apps/"
        else if (!strncmp(request_info->uri, APPS_URI, sizeof(APPS_URI) - 1)) {
            const char *app_name;
            app_name = request_info->uri + sizeof(APPS_URI) - 1;
            // start app
            if (!strcmp(request_info->request_method, "POST")) {
                handle_app_start(conn, request_info, app_name);
            // get app status
            } else if (!strcmp(request_info->request_method, "GET")) {
                handle_app_status(conn, request_info, app_name);
            } else {
                mg_send_http_error(conn, 501, "Not Implemented", "Not Implemented");
            }
        } 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_start() {
    DIALServer *ds = calloc(1, sizeof(DIALServer));
    struct mg_context *ctx;
  
    pthread_mutex_init(&ds->mux, NULL);
    ctx = mg_start(&request_handler, ds, DIAL_PORT);
    if (!ctx) {
        free(ds);
        return NULL;
    }
    ds->ctx = ctx;
    return ds;
}

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) {
    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;
        *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;
}

