/*
 * 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 {
    printf("/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) {
    printf("** 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 == '&' ))) {
        printf("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) {
    printf("** 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 );
        }
    }

    printf("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 )
    {
        printf("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) {
    printf("** 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) {
    printf("** 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);
    printf("usage: dialserver <options>\n");
    printf("options:\n");
    for( i = 0; i < numberOfOptions; i++ )
    {
        printf("        %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);
    printf("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;
    i = isAppRunning(spAppNetflix, NULL );
    printf("Netflix is %s\n", i ? "Running":"Not Running");
    i = isAppRunning( spAppYouTube, spAppYouTubeMatch );
    printf("YouTube is %s\n", i ? "Running":"Not Running");
    i = isAppRunning( spAppFiberTV, spAppFiberTVMatch );
    printf("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;
}

