from Ganga.GPIDev.Schema import *
from Ganga.GPIDev.Lib.Tasks.common import *
from Ganga.GPIDev.Lib.Tasks.IUnit import IUnit
from Ganga.GPIDev.Lib.Job.Job import JobError
from Ganga.GPIDev.Lib.Registry.JobRegistry import JobRegistrySlice, JobRegistrySliceProxy
from Ganga.Core.exceptions import ApplicationConfigurationError
from Ganga.GPIDev.Base.Proxy import addProxy, stripProxy
from Ganga.Utility.logging import getLogger
import Ganga.GPI as GPI

import os

logger = getLogger()

class ND280Unit_CSVEvtList(IUnit):
   _schema = Schema(Version(1,0), dict(IUnit._schema.datadict.items() + {
      'subpartid' : SimpleItem(defvalue=-1,typelist=['int'],doc='Index of this unit which is important when the original CSV file was split by the transform. Otherwise leave it at -1'),
      'eventswanted' : SimpleItem(defvalue='',typelist=['str','list'],doc='CSV list of run, subrun, and event numbers wanted.'),
    }.items()))

   _category = 'units'
   _name = 'ND280Unit_CSVEvtList'
   _exportmethods = IUnit._exportmethods + [ ]

   def __init__(self):
      super(ND280Unit_CSVEvtList, self).__init__()
      
   def createNewJob(self):
      """Create any jobs required for this unit"""      
      j = GPI.Job()
      j._impl.backend = self._getParent().backend.clone()
      j._impl.application = self._getParent().application.clone()
      j.inputdata = self.inputdata.clone()

      trf = self._getParent()
      task = trf._getParent()

      # copy across the outputfiles
      for f in trf.outputfiles:
         j.outputfiles += [f.clone()]

      j.inputsandbox = trf.inputsandbox

      if type(self.eventswanted) == type(''):
        subLines = self.eventswanted
      else:
        subLines = '\n'.join(self.eventswanted)
      # Base for the naming of each subjob's CSV file
      incsvfile = j._impl.application.csvfile
      tmpname = os.path.basename(incsvfile)
      if len(tmpname.split('.')) > 1:
        patterncsv = '.'.join(tmpname.split('.')[0:-1])+"_sub%d."+ tmpname.split('.')[-1]
      else:
        patterncsv = tmpname+"_sub%d"

      from Ganga.GPIDev.Lib.File import FileBuffer
      thiscsv = patterncsv % self.subpartid

      # Create the CSV file for this Unit
      j._impl.getInputWorkspace().writefile(FileBuffer(thiscsv,subLines),executable=0)
      j._impl.application.csvfile = j._impl.getInputWorkspace().getPath()+thiscsv
      j.inputsandbox.append(j._impl.getInputWorkspace().getPath()+thiscsv)

      # Base for the naming of each subjob's output file
      tmpname = os.path.basename(j._impl.application.outputfile)
      if len(tmpname.split('.')) > 1:
        patternout = '.'.join(tmpname.split('.')[0:-1])+"_sub%d."+ tmpname.split('.')[-1]
      else:
        patternout = tmpname+"_sub%d"
      j._impl.application.outputfile = patternout % self.subpartid

      # Sort out the splitter
      if trf.splitter:
         j.splitter = trf.splitter.clone()
         
      return j

   def checkMajorResubmit(self, job):
      """Check if a failed job shold be 'rebrokered' (new job created) rather than just resubmitted"""
      return False

   def majorResubmit(self, job):
      """Do any bookkeeping before a major resubmit is done"""
      super(ND280Unit_CSVEvtList,self).majorResubmit(job)

   def reset(self):
      """Reset the unit completely"""
      super(ND280Unit_CSVEvtList,self).reset()

   def updateStatus(self, status):
      """Update status hook"""
      super(ND280Unit_CSVEvtList,self).updateStatus(status)

   def checkForSubmission(self):
      """Additional checks for unit submission"""

      # call the base class
      if not super(ND280Unit_CSVEvtList,self).checkForSubmission():
         return False

      return True

   def copyOutput(self):
      """Copy the output data to local storage"""

      job = GPI.jobs(self.active_job_ids[0])
      
      if self.copy_output._name != "TaskLocalCopy" or job.outputdata._impl._name != "DQ2OutputDataset":
         logger.error("Cannot transfer from DS type '%s' to '%s'. Please contact plugin developer." % (job.outputdata._name, self.copy_output._name))
         return False

      # check which fies still need downloading
      to_download = []
      for f in job.outputfiles:
         
         # check for REs
         if self.copy_output.isValid( os.path.join(f.localDir, f.namePattern)) and not self.copy_output.isDownloaded( os.path.join(f.localDir, f.namePattern)):
            to_download.append(f)

      # is everything downloaded?
      if len(to_download) == 0:
         return True

      # nope, so pick the requested number and off we go
      for f in to_download:
         f.get()

      return False
