# @package      hubzero-submit-monitors
# @file         JobStageInput.py
# @copyright    Copyright (c) 2012-2020 The Regents of the University of California.
# @license      http://opensource.org/licenses/MIT MIT
#
# Copyright (c) 2012-2020 The Regents of the University of California.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# HUBzero is a registered trademark of The Regents of the University of California.
#
import os
import pwd
import logging

from hubzero.submit.LogMessage import getLogIDMessage as getLogMessage
from hubzero.submit.JobWSCore  import JobWSCore

COPYJOBINPUTS        = 'copyjobinputs.sh'
RECEIVEINPUTCOMMAND  = 'receiveinput.sh'
TIMESTAMPTRANSFERRED = '.__timestamp_transferred'

class JobStageInput(JobWSCore):
   def __init__(self,
                daemonsDirectory,
                daemonsConfigurationFile,
                infosDirectory,
                infosConfigurationFile,
                previousState,
                nextState):
      JobWSCore.__init__(self,daemonsDirectory,daemonsConfigurationFile,
                              infosDirectory,infosConfigurationFile,
                              'stageInput',previousState,nextState)

      self.logger = logging.getLogger(__name__)


   def processWSRequest(self,
                        wsJobId):
      jobStaged = False
      preStagedActiveJob = self.remoteJobMonitor.getActiveJobPreStaged(wsJobId)
      commandArgs = []
      siteName = preStagedActiveJob['siteName']
      siteInfo = self.sitesInfo.getSiteInfo(siteName)
      if siteInfo['fileMover']:
         fileMoverInfo = self.fileMoversInfo.getFileMoverInfo(siteInfo['fileMover'])
         if   fileMoverInfo['fileMoverType'] == 'tapis2':
            preStageStdin = None
            remoteBinDirectory = fileMoverInfo['remoteBinDirectory']
            stageJobInputCommand = os.path.join(remoteBinDirectory,COPYJOBINPUTS)
            commandArgs.append(stageJobInputCommand)
            commandArgs.append(os.path.join(preStagedActiveJob['preStageDirectory'],preStagedActiveJob['instanceToken']))
            commandArgs.append(fileMoverInfo['tapisStorageSystem'])
            commandArgs.append(preStagedActiveJob['instanceToken'])
            commandArgs.append("%s.%s" % (TIMESTAMPTRANSFERRED,preStagedActiveJob['stagingHandle']))
         elif fileMoverInfo['fileMoverType'] == 'tapis3':
            preStageStdin = None
            remoteBinDirectory = fileMoverInfo['remoteBinDirectory']
            stageJobInputCommand = os.path.join(remoteBinDirectory,COPYJOBINPUTS)
            commandArgs.append(stageJobInputCommand)
            commandArgs.append(os.path.join(preStagedActiveJob['preStageDirectory'],preStagedActiveJob['instanceToken']))
            commandArgs.append(fileMoverInfo['tapisStorageSystem'])
            commandArgs.append(preStagedActiveJob['instanceToken'])
            commandArgs.append("%s.%s" % (TIMESTAMPTRANSFERRED,preStagedActiveJob['stagingHandle']))
         elif fileMoverInfo['fileMoverType'] == 'ssh':
            preStagedFile = "%s_input.tar.gz" % (preStagedActiveJob['stagingHandle'])
            preStagedPath = os.path.join(preStagedActiveJob['preStageDirectory'],
                                         preStagedActiveJob['instanceToken'],preStagedFile)
            preStageStdin = preStagedPath

            commandArgs += "ssh -T -x -a".split()
            commandArgs += siteInfo['sshOptions'].split()
            identityPaths = self.remoteIdentityManager.queryUserIdentities(siteInfo['identityManagers'],
                                                                           pwd.getpwuid(os.getuid()).pw_name)
            commandArgs += ['-i',identityPaths['individualSSH']]
            commandArgs += ['-p',str(siteInfo['venuePort'])]
            commandArgs.append("%s@%s" % (siteInfo['remoteUser'],siteInfo['venues'][0]))
            remoteWorkingDirectory = os.path.join(siteInfo['remoteScratchDirectory'],"%s_%s" % \
                                               (preStagedActiveJob['stagingHandle'],preStagedActiveJob['instanceToken']))
            remoteScratchDirectory = remoteWorkingDirectory
            timestampTransferred = "%s.%s" % (TIMESTAMPTRANSFERRED,preStagedActiveJob['stagingHandle'])
            remoteBinDirectory = siteInfo['remoteBinDirectory']
            stageJobInputCommand = " ".join([os.path.join(remoteBinDirectory,RECEIVEINPUTCOMMAND),
                                             remoteWorkingDirectory,
                                             remoteScratchDirectory,
                                             timestampTransferred])
            commandArgs.append(stageJobInputCommand)

         del fileMoverInfo

         exitStatus,stdOutput,stdError = self.executeCommand(commandArgs,stdin=preStageStdin)
         if exitStatus == 0:
            self.logger.log(logging.DEBUG,getLogMessage(stdOutput))
            self.logger.log(logging.DEBUG,getLogMessage(stdError))
         else:
            self.logger.log(logging.ERROR,getLogMessage(stdOutput))
            self.logger.log(logging.ERROR,getLogMessage(stdError))

         if exitStatus == 0:
            jobStaged = True
      del siteInfo

      return(jobStaged)


