/*
 * externalplayer-player.c: A plugin for the Video Disk Recorder
 *
 * See the README file for copyright information and how to reach the author.
 *
 * $Id$
 */

#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>

#include "externalplayer-player.h"

pid_t pid = 0;
void killProcess(int noParam) {
  if (kill(pid, 0) == 0) {
    isyslog("externalplayer-plugin: player did not terminate properly. Killing process %i", pid);
    kill(pid, SIGKILL);
    signal(SIGALRM, SIG_DFL);
  }
  pid = 0;
}

cPlayerExternalplayer::cPlayerExternalplayer(ePlayMode playMode, sPlayerArgs * nConfig, int nFdReadPipe)
    : cPlayer(playMode) {
  config = nConfig;
  activated = false;
  isyslog("externalplayer-plugin: player starts %d %d",playMode, config->deactivateRemotes );

  fdReadPipe = nFdReadPipe;

  if (config->deactivateRemotes) {
    remotesDisable = new cRemotesDisable();
  }
  else {
    remotesDisable = NULL;
  }
  Activate(true);
}

cPlayerExternalplayer::~cPlayerExternalplayer() {
  isyslog("externalplayer-plugin: player stops");
  Activate(false);
  activated = false;
  delete remotesDisable;
  pid = 0;
}

void cPlayerExternalplayer::Activate(bool On) {
  isyslog("externalplayer-plugin: Activate \"%d\"", On);
      
  if (On && !activated) {
    activated = true;  
    if (remotesDisable != NULL) {
      remotesDisable->deactivateRemotes();
    }

    int nPid = fork();
    if (nPid == 0) {
      if (config->slaveMode) {
        dup2(fdReadPipe, STDIN_FILENO);
      }

      isyslog("externalplayer-plugin: executing \"%s\"", config->playerCommand.c_str());
      execle("/bin/sh", "sh", "-c", config->playerCommand.c_str(), NULL, environ);
      isyslog("externalplayer-plugin: execution (of /bin/sh) failed");
      _exit(0);
    }
    else {
      pid = nPid;
      isyslog("externalplayer-plugin: PID of child process: %i", pid);
    }
  }
  else {
    if ( !On && activated )
    {
       if (remotesDisable != NULL) {
         remotesDisable->reactivateRemotes();
       }
       activated = false;
   
       if (pid != 0) {
         if (kill(pid, 0) == 0) {
           kill(pid, SIGTERM);
           alarm(2);
           signal(SIGALRM, killProcess);
         }
         pid = 0;
       }
      }
   }
}

bool cPlayerExternalplayer::isActive() {
  return pid ? (waitpid(pid, NULL, WNOHANG) == 0) : false;
}
