/*
 * 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 <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"

#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 = "content_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;
}


/* 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","w");
  if (!runapp) {
    fprintf(stderr, "Couldn't open /tmp/runapp 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 file\n");
    }
  }
  fsync(fileno(runapp));
  fclose(runapp);
  runapp=NULL;


  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 **\n");

    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 stop
    *pCanStop = 1;
    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_start();
    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);
    DIAL_register_app(ds, "YouTube", &cb_yt, NULL);
    if (strcmp(spUiType, "oregano") == 0) {
      DIAL_register_app(ds, "GoogleFiberTV", &cb_gf, NULL);
    } else {
      DIAL_register_app(ds, "FiberTV", &cb_ft, NULL);
    }
    gDialPort = DIAL_get_port(ds);
    fprintf(stderr, "launcher listening on gDialPort %d\n", gDialPort);
    run_ssdp(gDialPort, spFriendlyName, spModelName, spUuid, &spIpAddress);

    DIAL_stop(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[]) 
{
    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;
}

