'''The client side of the multi_facility_process_helper.
Mostly a utility class with a lot of convenience methods.'''
from __future__ import print_function

import sys
import os.path
import json
import subprocess
import socket
import globals
import toolconfig


def executeCommandsOnFacility(facility, commandsAndArgs):
    '''Executes a list of commands on the specified facility using ssh and the multi_facility_process_helper.
    facility - This is the facility name.
    commandsAndArgs - A list of tuples - each tuple has two components. First component is a string command. Second command is a jsonable arg. Both are mandatory.
    We return the deserialized contents of executing the set of commands on the remote facility as a list of objects
    '''
    facilityConfig = toolconfig.getConfigForFacility(facility)
    # Each facility has a config element that tells us machine and use credentials.
    ssh    = facilityConfig['ssh']

    # If destination facility is the same as the origin, do not use ssh
    destHost = ssh.split('@')[-1]
    origHost = socket.gethostname()
    mfHelperPath = 'multi_facility_process_helper'
    if destHost == origHost:
       if globals.verbose:
           print("Destination and origin facilities are the same, no ssh needed")
       conargs=[mfHelperPath]
    elif toolconfig.usesGateway(facility):
       gateway = facilityConfig['gateway']
       conargs=['ssh','-x', gateway,'ssh -x -o BatchMode=yes ' ,ssh, mfHelperPath]
    else:
       conargs=['ssh','-x',ssh,'-o BatchMode=yes', mfHelperPath]

    if globals.verbose:
        conargs.append("-v")

    try:
        proc = subprocess.Popen(conargs,
                         stdin=subprocess.PIPE,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE)
        commandStr = json.dumps(commandsAndArgs)
        if globals.verbose:
            if destHost == origHost:
                print("Sending to multi_facility_process_helper - {0}".format(commandStr))
            else:
                print("Sending to remote multi_facility_process_helper - {0} on {1} with ssh = {2} using {3} gateway".format(commandStr, facility, ssh, gateway if toolconfig.usesGateway(facility) else ' no '))

        [stdoutdata, stderrdata] = proc.communicate(commandStr)

        if globals.verbose:
            print("stderr {0}".format(stderrdata))
        if globals.verbose:
            print("stdout {0}".format(stdoutdata))

        if proc.returncode != 0:
           err_msg = {'name':facility,'stdout':stdoutdata,'stderr':stderrdata,'rc':proc.returncode}
           raise connectionException(err_msg)
        try:
            ret = json.loads(stdoutdata)
        except ValueError as e:
            print("stderr {0}".format(stderrdata))
            print("stdout {0}".format(stdoutdata))
            raise e
        if globals.verbose:
            print("Return from multi_facility_process_helper {0}".format(ret))
        return ret
    except subprocess.CalledProcessError:
        return ""



class connectionException(Exception):
      pass
