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

    // TODO(steineldar): Verify that the args string is a valid URL query param.
    for (int n = 0; args[n] != 0; ++n) {
      char c = args[n];
      if (!(( '0' <= c && c <= '9' ) ||
            ( 'a' <= c && c <= 'z' ) ||
            ( 'A' <= c && c <= 'Z' ) ||
            ( c == '=' || c == '-' || c == '_' || c == '&' ))) {
        fprintf(stderr, "Invalid char [%d] = %c", (int) c, c);
        args = "";
        break;
      }
    }

    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;

    waitpid((pid_t)run_id, NULL, WNOHANG); // reap child
    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);
        waitpid((pid_t)pid, NULL, 0); // reap child
    }
}

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

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

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};
    struct DIALAppCallbacks cb_yt = {youtube_start, youtube_stop, youtube_status};
    struct DIALAppCallbacks cb_ft = {fibertv_start, fibertv_stop, fibertv_status};

    DIAL_register_app(ds, "Netflix", &cb_nf, NULL);
    DIAL_register_app(ds, "YouTube", &cb_yt, NULL);
    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);

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

