#!/usr/bin/python2
# -*- Mode:python; c-file-style:"gnu"; indent-tabs-mode:nil -*- */
#
# Copyright (C) 2014 University of Arizona
# Author: Jerald Paul Abraham <jeraldabraham@email.arizona.edu>
# See COPYING for copyright and distribution information.
#

import errno
import subprocess
import multiprocessing as mp

class process_manager:

    manager = mp.Manager()
    processes = dict()
    subprocesses = manager.dict()
    results = manager.dict()

    def runProcess(self, processKey, processCallFormat, message, subprocesses, results):
        print message
        process = subprocess.Popen(
            processCallFormat, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
        subprocesses[processKey] = process
        try:
            stdout, stderr = process.communicate()
            returnCode = process.returncode
            results[processKey] = (returnCode, stdout, stderr)
        except IOError as e:
            pass

    def startProcess(self, processKey, processCallFormat, message):
        self.processes[processKey] = mp.Process(
            target = self.runProcess,
                args = [processKey, processCallFormat, message, self.subprocesses, self.results])
        self.processes[processKey].start()

    def killProcess(self, processKey):
        if processKey not in self.results:
            self.subprocesses[processKey].terminate()

    def hasProcessCompleted(self, processKey):
        if processKey in self.results:
            return True
        else:
            return False

    def waitForProcessCompletion(self, processKey, waitTime):
        self.processes[processKey].join(waitTime)

    def getProcessReturnCode(self, processKey):
        if processKey in self.results:
            (returnCode, stdout, stderr) = self.results[processKey]
            return returnCode
        else:
            print "Invalid processKey provided - " + processKey
            return -1

    def getProcessError(self, processKey):
        if processKey in self.results:
            (returnCode, stdout, stderr) = self.results[processKey]
            return stderr
        else:
            return "Error not available for processKey - " + processKey

    def startNfd(self):
        self.startProcess("nfd", ["sudo", "nfd"], "-> Starting NFD")

    def killNfd(self):
        self.killProcess("nfd")
