/*
 * 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 <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <dirent.h>
#include <regex.h>

#include "dial_server.h"
#include "dial_options.h"
#include <signal.h>

#define BUFSIZE 256

static char *spDefaultFriendlyName = "Google Fiber TV Box";
static char *spDefaultModelName = "GFHD100";
static char *spDefaultUuid = "0";
static char spFriendlyName[BUFSIZE];
static char spModelName[BUFSIZE];
static char spUuid[BUFSIZE];
static char spUiType[BUFSIZE];
static int gDialPort;

static char *spAppNetflix = "netflix";      // name of the netflix executable
static char *defaultLaunchParam = "source_type=12";

static char *spAppYouTube = "browser_shell";
static char *spAppYouTubeMatch = "www.youtube.com/tv";

static char *spAppFiberTV = "miniclient";
static char *spAppFiberTVMatch = NULL;

// Adding 20 bytes for prepended source_type for Netflix
static char sQueryParam[DIAL_MAX_PAYLOAD+20];

static const char *spIpAddress;

static int doesMatch( char* pzExp, char* pzStr)
{
    regex_t exp;
    int ret;
    int match = 0;
    if ((ret = regcomp( &exp, pzExp, REG_EXTENDED ))) {
        char errbuf[1024] = {0,};
        regerror(ret, &exp, errbuf, sizeof(errbuf));
        fprintf( stderr, "regexp error: %s", errbuf );
    } else {
        regmatch_t matches[1];
        if( regexec( &exp, pzStr, 1, matches, 0 ) == 0 ) {
            match = 1;
        }
    }
    regfree(&exp);
    return match;
}

// For Fiber we do not let DIAL handle SIGTERM, as we consider that a killing
// signal (pkillwait uses it first).
/*
void signalHandler(int signal)
{
    switch(signal)
    {
        case SIGTERM:
            // just ignore this, we don't want to die
            break;
    }
}
*/

/* The URL encoding source code was obtained here:
 * http://www.geekhideout.com/urlcode.shtml
 */

/* Converts a hex character to its integer value */
char from_hex(char ch) {
    return isdigit(ch) ? ch - '0' : tolower(ch) - 'a' + 10;
}

/* Converts an integer value to its hex character*/
char to_hex(char code) {
    static char hex[] = "0123456789abcdef";
  return hex[code & 15];
}

/* Returns a url-encoded version of str */
/* IMPORTANT: be sure to free() the returned string after use */
char *url_encode(const char *str) {
    const char *pstr;
    char *buf, *pbuf;
    pstr = str;
    buf = malloc(strlen(str) * 3 + 1);
    pbuf = buf;
    if( buf )
    {
        while (*pstr) {
            if (isalnum(*pstr) || *pstr == '-' || *pstr == '_' || *pstr == '.' || *pstr == '~')
                *pbuf++ = *pstr;
            else if (*pstr == ' ')
                *pbuf++ = '+';
            else
                *pbuf++ = '%', *pbuf++ = to_hex(*pstr >> 4), *pbuf++ = to_hex(*pstr & 15);
            pstr++;
        }
        *pbuf = '\0';
    }
    return buf;
}

/*
 * End of URL ENCODE source
 */

/*
 * This function will walk /proc and look for the application in
 * /proc/<PID>/comm. and /proc/<PID>/cmdline to find it's command (executable
 * name) and command line (if needed).
 * Implementors can override this function with an equivalent.
 */
static int isAppRunning( char *pzName, char *pzCommandPattern ) {
  DIR* proc_fd = opendir("/proc");
  if( proc_fd != NULL ) {
    struct dirent* procEntry;
    while((procEntry=readdir(proc_fd)) != NULL) {
      if( doesMatch( "^[0-9][0-9]*$", procEntry->d_name ) ) {
        char exePath[64] = {0,};
        char link[256] = {0,};
        char cmdlinePath[64] = {0,};
        char buffer[1024] = {0,};
        int len;
        sprintf( exePath, "/proc/%s/exe", procEntry->d_name);
        sprintf( cmdlinePath, "/proc/%s/cmdline", procEntry->d_name);

        if( (len = readlink( exePath, link, sizeof(link)-1)) != -1 ) {
          char executable[256] = {0,};
          strcat( executable, pzName );
          strcat( executable, "$" );
          // TODO: Make this search for EOL to prevent false positivies
          if( !doesMatch( executable, link ) ) {
            continue;
          }
          // else //fall through, we found it
        }
        else continue;

        if (pzCommandPattern != NULL) {
          FILE *cmdline = fopen(cmdlinePath, "r");
          if (!cmdline) {
            continue;
          }
          if (fgets(buffer, 1024, cmdline) == NULL) {
            fclose(cmdline);
            continue;
          }
          fclose(cmdline);

          if (!doesMatch( pzCommandPattern, buffer )) {
            continue;
          }
        }

        closedir(proc_fd);
        return atoi(procEntry->d_name);
      }
    }

    closedir(proc_fd);
  } else {
    fprintf(stderr, "/proc failed to open\n");
  }
  return 0;
}

/* Running an application is done through the runminiclient script */
static pid_t runApplication( const char * const args[], DIAL_run_t *run_id ) {
  const char * const script_args[] = {"/etc/init.d/S99miniclient", "restart", 0};

  /* Write application information to /tmp/runapp */
  FILE *runapp = fopen("/tmp/runapp.tmp","w");
  if (!runapp) {
    fprintf(stderr, "Couldn't open /tmp/runapp.tmp file\n");
    return kDIALStatusStopped;
  }
  for(int i = 0; args[i]; ++i) {
    int outputCharacters = fprintf(runapp, "%s ", args[i]);
    if (outputCharacters<0) {
      fprintf(stderr, "Error writing to /tmp/runapp.tmp file\n");
      fclose(runapp);
      return kDIALStatusStopped;
    }
  }
  fsync(fileno(runapp));
  fclose(runapp);
  runapp=NULL;
  if (rename("/tmp/runapp.tmp", "/tmp/runapp")) {
    fprintf(stderr, "Error renaming /tmp/runapp.tmp file\n");
    return kDIALStatusStopped;
  }


  pid_t pid = fork();
  if (pid != -1) {
    if (!pid) { // child
      // Close all descriptors except stdin,stdout,stderr
      int fd, maxfd;
      maxfd = sysconf(_SC_OPEN_MAX);
      for (fd=3;fd<maxfd;fd++) {
        close(fd);
      }
      execv(*script_args, (char * const *) script_args);
      // It won't reach this unless there was an error
      fprintf(stderr, "Error executing %s\n", *script_args);
      exit(1);
    } else {
      *run_id = (void *)(long)pid; // parent PID
      // Wait until the script S99miniclient is done before continuing
      waitpid(pid, NULL, 0);
      // TODO(jfthibert) Should we try to wait a few seconds until the actual
      // program is started?
    }
    return kDIALStatusRunning;
  } else {
    return kDIALStatusStopped;
  }
}


/* Compare the applications last launch parameters with the new parameters.
 * If they match, return false
 * If they don't match, return true
 */
static int shouldRelaunch(
    DIALServer *pServer,
    const char *pAppName,
    const char *args )
{
    return ( strncmp( DIAL_get_payload(pServer, pAppName), args, DIAL_MAX_PAYLOAD ) != 0 );
}

static DIALStatus youtube_start(DIALServer *ds, const char *appname,
                                const char *args, size_t arglen,
                                DIAL_run_t *run_id, void *callback_data) {
    fprintf(stderr, "** LAUNCH YouTube ** with args %s\n\n", args);

    char url[512] = {0,};
    int urlLength = snprintf( url, sizeof(url), "https://www.youtube.com/tv?%s", args);
    if (urlLength>=sizeof(url)) {
      fprintf(stderr, "Warning, YouTube URL was truncated (%d>=%d)\n", urlLength, sizeof(url));
    }

    const char * const youtube_args[] = { "youtube",
      url, NULL
    };
    runApplication( youtube_args, run_id );

    return kDIALStatusRunning;
}

static DIALStatus youtube_status(DIALServer *ds, const char *appname,
                                 DIAL_run_t run_id, int *pCanStop, void *callback_data) {
    // YouTube can stop
    *pCanStop = 1;
    return isAppRunning( spAppYouTube, spAppYouTubeMatch ) ? kDIALStatusRunning : kDIALStatusStopped;
}

static void youtube_stop(DIALServer *ds, const char *appname, DIAL_run_t run_id,
                         void *callback_data) {
    fprintf(stderr, "** KILL YouTube **\n");
    pid_t pid;
    if ((pid = isAppRunning( spAppYouTube, spAppYouTubeMatch ))) {
        kill(pid, SIGTERM);
    }
}

static DIALStatus netflix_start(DIALServer *ds, const char *appname,
                                const char *args, size_t arglen,
                                DIAL_run_t *run_id, void *callback_data) {
    int shouldRelaunchApp = 0;
    int payloadLen = 0;
    int appPid = 0;

    // only launch Netflix if it isn't running
    appPid = isAppRunning( spAppNetflix, NULL );
    shouldRelaunchApp = shouldRelaunch( ds, appname, args );

    // construct the payload to determine if it has changed from the previous launch
    payloadLen = strlen(args);
    memset( sQueryParam, 0, DIAL_MAX_PAYLOAD );
    strcat( sQueryParam, defaultLaunchParam );
    if( payloadLen )
    {
        char * pUrlEncodedParams;
        pUrlEncodedParams = url_encode( args );
        if( pUrlEncodedParams )
        {
            strcat( sQueryParam, "&dial=");
            strcat( sQueryParam, pUrlEncodedParams );
            free( pUrlEncodedParams );
        }
    }

    fprintf(stderr, "appPid = %s, shouldRelaunch = %s queryParams = %s\n",
          appPid?"TRUE":"FALSE",
          shouldRelaunchApp?"TRUE":"FALSE",
          sQueryParam );

    // if its not running, launch it.  The Netflix application should
    // never be relaunched
    if( !appPid )
    {
        const char * const netflix_args[] = {"netflix", "-Q", sQueryParam, 0};
        return runApplication( netflix_args, run_id );
    }
    else return kDIALStatusRunning;
}

static DIALStatus netflix_status(DIALServer *ds, const char *appname,
                                 DIAL_run_t run_id, int* pCanStop, void *callback_data) {
    // Netflix application can't stop
    *pCanStop = 0;

    return isAppRunning( spAppNetflix, NULL ) ? kDIALStatusRunning : kDIALStatusStopped;
}

static void netflix_stop(DIALServer *ds, const char *appname, DIAL_run_t run_id,
                         void *callback_data) {
    int pid;
    pid = isAppRunning( spAppNetflix, NULL );
    if( pid )
    {
        fprintf(stderr, "Killing pid %d\n", pid);
        kill((pid_t)pid, SIGTERM);
    }
}

static DIALStatus fibertv_start(DIALServer *ds, const char *appname,
                                const char *args, size_t arglen,
                                DIAL_run_t *run_id, void *callback_data) {
    fprintf(stderr, "** LAUNCH FiberTV **\n");

    const char * const miniclient_args[] = { "miniclient", NULL };
    runApplication( miniclient_args, run_id );

    return kDIALStatusRunning;
}

static DIALStatus fibertv_status(DIALServer *ds, const char *appname,
                                 DIAL_run_t run_id, int *pCanStop, void *callback_data) {
    // FiberTV can stop
    *pCanStop = 1;
    return isAppRunning( spAppFiberTV, spAppFiberTVMatch ) ? kDIALStatusRunning : kDIALStatusStopped;
}

static void fibertv_stop(DIALServer *ds, const char *appname, DIAL_run_t run_id,
                         void *callback_data) {
    fprintf(stderr, "** KILL FiberTV **\n");
    pid_t pid;
    if ((pid = isAppRunning( spAppFiberTV, spAppFiberTVMatch ))) {
        kill(pid, SIGTERM);
    }
}

static DIALStatus basil_start(DIALServer *ds, const char *appname,
                                const char *args, size_t arglen,
                                DIAL_run_t *run_id, void *callback_data) {
    fprintf(stderr, "** LAUNCH GoogleFiberTV **\n");
    return kDIALStatusRunning; // Basil is always running
}

static DIALStatus basil_status(DIALServer *ds, const char *appname,
                                 DIAL_run_t run_id, int *pCanStop, void *callback_data) {
    *pCanStop = 0;
    return kDIALStatusRunning; // Basil is always running
}

static struct CastServiceData basil_service_data(DIALServer *ds, const char *appname,
                                 DIAL_run_t run_id, void *callback_data) {
    struct CastServiceData serviceData;
    serviceData.connection_svc_host = spIpAddress;
    serviceData.connection_svc_port = 5153;
    serviceData.connection_svc_path = "/connections";
    serviceData.protocol = "marjoram";
    return serviceData;
}

static void basil_stop(DIALServer *ds, const char *appname, DIAL_run_t run_id,
                         void *callback_data) {
    fprintf(stderr, "** KILL GoogleFiberTV (ignored) **\n");
    // Basil cannot be killed, but log the attempt
}

void run_ssdp(int port, const char *pFriendlyName, const char * pModelName, const char *pUuid, const char **ppIpAddress);

static void printUsage()
{
    int i, numberOfOptions = sizeof(gDialOptions) / sizeof(dial_options_t);
    fprintf(stderr, "usage: dialserver <options>\n");
    fprintf(stderr, "options:\n");
    for( i = 0; i < numberOfOptions; i++ )
    {
        fprintf(stderr, "        %s|%s [value]: %s\n",
            gDialOptions[i].pOption,
            gDialOptions[i].pLongOption,
            gDialOptions[i].pOptionDescription );
    }
}

static void setValue( char * pSource, char dest[] )
{
    // Destination is always one of our static buffers with size BUFSIZE
    memset( dest, 0, BUFSIZE );
    strncpy( dest, pSource, BUFSIZE-1 );
}

void runDial(void)
{
    DIALServer *ds;
    ds = DIAL_create();
    struct DIALAppCallbacks cb_nf = {netflix_start, netflix_stop, netflix_status, NULL, NULL};
    struct DIALAppCallbacks cb_yt = {youtube_start, youtube_stop, youtube_status, NULL, NULL};
    struct DIALAppCallbacks cb_ft = {fibertv_start, fibertv_stop, fibertv_status, NULL, NULL};
    struct DIALAppCallbacks cb_gf = {basil_start, basil_stop, basil_status, basil_service_data, NULL};

    DIAL_register_app(ds, "Netflix", &cb_nf, NULL, 1, ".netflix.com");
    DIAL_register_app(ds, "YouTube", &cb_yt, NULL, 1, ".youtube.com");
    if (strcmp(spUiType, "oregano") == 0) {
      DIAL_register_app(ds, "GoogleFiberTV", &cb_gf, NULL, 0, NULL);
    } else {
      DIAL_register_app(ds, "FiberTV", &cb_ft, NULL, 0, NULL);
    }
    DIAL_start(ds);

    gDialPort = DIAL_get_port(ds);
    fprintf(stderr, "launcher listening on gDialPort %d\n", gDialPort);
    run_ssdp(gDialPort, spFriendlyName, spModelName, spUuid, &spIpAddress);

    DIAL_stop(ds);
    free(ds);
}

static void processOption( int index, char * pOption )
{
    switch(index)
    {
        case 0: // Friendly name
            setValue( pOption, spFriendlyName );
            break;
        case 1: // Model Name
            setValue( pOption, spModelName );
            break;
        case 2: // UUID
            setValue( pOption, spUuid );
            break;
        case 3: // UI type
            setValue( pOption, spUiType );
            break;
        default:
            // Should not get here
            fprintf( stderr, "Option %d not valid\n", index);
            exit(1);
    }
}

int main(int argc, char* argv[])
{
    // We want DIAL to die on a SIGTERM - pkillwait sends SIGTERM first.
    /*
    struct sigaction action;
    action.sa_handler = signalHandler;
    sigemptyset(&action.sa_mask);
    action.sa_flags = 0;
    sigaction(SIGTERM, &action, NULL);
    */

    srand(time(NULL));
    int i;

    // Set stdout to unbuffered mode to avoid delayed logs
    setvbuf(stdout, NULL, _IONBF, 0);

    i = isAppRunning(spAppNetflix, NULL );
    fprintf(stderr, "Netflix is %s\n", i ? "Running":"Not Running");
    i = isAppRunning( spAppYouTube, spAppYouTubeMatch );
    fprintf(stderr, "YouTube is %s\n", i ? "Running":"Not Running");
    i = isAppRunning( spAppFiberTV, spAppFiberTVMatch );
    fprintf(stderr, "FiberTV is %s\n", i ? "Running":"Not Running");

    // set all defaults
    setValue(spDefaultFriendlyName, spFriendlyName );
    setValue(spDefaultModelName, spModelName );
    setValue(spDefaultUuid, spUuid );

    // Process command line options
    // Loop through pairs of command line options.
    for( i = 1; i < argc; i+=2 )
    {
        int numberOfOptions = sizeof(gDialOptions) / sizeof(dial_options_t);
        while( --numberOfOptions >= 0 )
        {
            int shortLen, longLen;
            shortLen = strlen(gDialOptions[numberOfOptions].pOption);
            longLen = strlen(gDialOptions[numberOfOptions].pLongOption);
            if( ( ( strncmp( argv[i], gDialOptions[numberOfOptions].pOption, shortLen ) == 0 ) ||
                ( strncmp( argv[i], gDialOptions[numberOfOptions].pLongOption, longLen ) == 0 ) ) &&
                ( (i+1) < argc ) )
            {
                processOption( numberOfOptions, argv[i+1] );
                break;
            }
        }
        // if we don't find an option in our list, bail out.
        if( numberOfOptions < 0 )
        {
            printUsage();
            exit(1);
        }
    }
    runDial();

    return 0;
}

