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

// Returns 0 for false, non-zero for true.
static int isWirelessTV() {
  FILE* fp;
  char active_wan[6];

  fp = popen("activewan", "r");
  if (fp == NULL) {
    fprintf(stderr, "Could not run activewan; assuming wired connection\n");
    return 0;
  }

  fgets(active_wan, sizeof(active_wan) - 1, fp);
  pclose(fp);

  return strncmp(active_wan, "wcli0", 5) == 0 ||
         strncmp(active_wan, "wcli1", 5) == 0;
}

/*
 * 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;
  int appclientUid = 201;
  int videoGid = 200;
  if (chown("/tmp/runapp.tmp", appclientUid, videoGid)) {
    fprintf(stderr, "Error chowning /tmp/runapp.tmp file.  App launch may fail.");
  }
  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&%s",
                 isWirelessTV() ? "wireless" : "wired", 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);
    }
    if (DIAL_start(ds)) {
        fprintf(stderr, "DIAL_start failed, exiting.\n");
        exit(1);
    }

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

