# @package      hubzero-submit-monitors
# @file         JobProcessor.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 requests
import time
import traceback
import logging

from hubzero.submit.LogMessage       import getLogIDMessage as getLogMessage
from hubzero.submit.DaemonsInfo      import DaemonsInfo
from hubzero.submit.RemoteJobMonitor import RemoteJobMonitor

class JobProcessor:
   def __init__(self,
                daemonsDirectory,
                daemonsConfigurationFile):
      self.logger = logging.getLogger(__name__)

      self.daemonsDirectory         = daemonsDirectory
      self.daemonsConfigurationFile = daemonsConfigurationFile

      self.remoteJobMonitor = None
      self.wsTaskURL        = None

      self.daemonsInfo = None
      self.settingInfo = False

      self.terminating = False


   def setInfo(self):
      errorInSetInfo = False
      if not self.settingInfo:
         self.settingInfo = True

         configFilePath = os.path.join(self.daemonsDirectory,self.daemonsConfigurationFile)
         self.daemonsInfo  = DaemonsInfo(configFilePath)
         self.jobListenURI = self.daemonsInfo.getDaemonListenURI('jobMonitor','tcp')

         self.remoteJobMonitor = RemoteJobMonitor(self.jobListenURI)

         self.settingInfo = False

      return(errorInSetInfo)


   def terminate(self):
      if not self.terminating:
         self.terminating = True


   def registerJobActionProcess(self,
                                action):
      actionProcessPID = os.getpid()
      now              = time.time()

      success,timeBetween = self.remoteJobMonitor.registerJobActionProcess(action,actionProcessPID,now)

      return(success,timeBetween)


   def releaseRegisteredJobs(self):
      nReleasedJobs = self.remoteJobMonitor.releaseRegisteredJobs()

      now = time.time()
      self.remoteJobMonitor.updateJobActionProcessActivityTime('Processor',now)

      return(nReleasedJobs)


   def postEnrolledWSJobs(self):
      nPostedJobs = 0
      if not self.wsTaskURL:
         self.wsTaskURL = self.remoteJobMonitor.getWSTaskURL('register')

      enrolledWSJobIds = self.remoteJobMonitor.getEnrolledWSJobIds()
      for wsJobId in enrolledWSJobIds:
         postEnrolledURL = '/'.join([self.wsTaskURL,wsJobId])
         try:
            response = requests.post(postEnrolledURL)
         except:
            self.logger.log(logging.ERROR,getLogMessage(traceback.format_exc()))
         else:
            status = response.status_code
            self.logger.log(logging.DEBUG,getLogMessage(response.json()))
            if status == 200:
               self.remoteJobMonitor.markWSjobAsPosting(wsJobId)
               nPostedJobs += 1
         time.sleep(1)

      return(nPostedJobs)


   def markActiveJobsAsComplete(self):
      self.remoteJobMonitor.markActiveJobsAsComplete()


