"""
Generate the full fake DAG for one exposure
Generate the jobs for fake stage
"""
from ipp.Gpc1Manager import Gpc1Manager as Gpc1Manager
from ipp.helpers import mkdir
from ipp.constants.Globals import Globals as GlobalConstants
from ipp.constants.Fake import Fake as FakeConstants

#################################################################
class FakeManager(Gpc1Manager):
    """
    Fake stage implementation
    """
    SCRIPT_NAME = '/home/panstarrs/ippdor/local/bin/generate_fake_jobs.py'

    def __init__(self,
                 label,
                 exposure_name,
                 recipient):
        """
        Creates a connector to the gpc1 database as well as local and
        nfs directories (their name is fake)
        """
        Gpc1Manager.__init__(self, recipient=recipient)
        self.label = label
        self.exposure_name = exposure_name
        self.fake_directory = '%s/%s/%s/fake' % (GlobalConstants.LOCAL_TMP_DIR, 
                                                label, 
                                                exposure_name)
        mkdir(self.fake_directory)

    def build_new_fake_jobs(self, stage_name = 'C010'):
        """Build the jobs file for the C010 node
        """
        query = """
SELECT
    chipProcessedImfile.exp_id,
    fakeRun.fake_id,
    chipProcessedImfile.class_id,
    chipProcessedImfile.path_base,
    camProcessedExp.path_base,
    rawExp.camera,
    fakeRun.reduction,
    fakeRun.dvodb,
    fakeRun.workdir
FROM fakeRun
JOIN camRun USING(cam_id)
JOIN camProcessedExp USING(cam_id)
JOIN chipRun USING(chip_id)
JOIN chipProcessedImfile USING(chip_id,exp_id)
JOIN rawExp USING(exp_id)
--    ON chipProcessedImfile.exp_id = rawExp.exp_id
LEFT JOIN fakeProcessedImfile
    ON fakeRun.fake_id = fakeProcessedImfile.fake_id
    AND chipProcessedImfile.class_id = fakeProcessedImfile.class_id
LEFT JOIN fakeMask
    ON fakeRun.label = fakeMask.label
WHERE
    ((fakeRun.state = 'new'
        AND fakeProcessedImfile.fake_id IS NULL
        AND fakeProcessedImfile.class_id IS NULL
    )
    OR (fakeRun.state = 'update'
        AND fakeProcessedImfile.data_state = 'cleaned')
    )
    AND fakeMask.label IS NULL
    AND fakeRun.label='%s'
    AND rawExp.exp_id = %d
""" % (self.label, self.get_exposure_id(self.exposure_name))
        fakes = self.multiple_query(query)
        jobs_filename = '%s/%s.jobs' % (self.fake_directory, stage_name)
        print "Generating Condor jobs file [%s] for processing of %d fake (stage %s)" % (jobs_filename, 
                                                                                         len(fakes), 
                                                                                         stage_name)
        output = open(jobs_filename, 'w')
        output.write('Executable = /home/panstarrs/ippdor/local/bin/encapsulate_fake.sh\n')
        output.write('Universe = vanilla\n')
        output.write('Output = %s/out.%s.%s.fake_%s\n' % (GlobalConstants.NFS_TMP_DIR,
                                                          self.label, 
                                                          self.exposure_name, 
                                                          stage_name))
        output.write('Error = %s/err.%s.%s.fake_%s\n' % (GlobalConstants.NFS_TMP_DIR,
                                                         self.label, 
                                                         self.exposure_name, 
                                                         stage_name))
        output.write('Log = %s/%s_fake_%s.log\n' % (GlobalConstants.LOCAL_TMP_DIR,
                                                    self.exposure_name, 
                                                    stage_name))
        output.write('Requirements = %s\n' % FakeConstants.REQUIREMENTS)
        output.write('Notification = Error\n')
        output.write('\n')
        output.write('getenv = True\n')
        output.write('\n')
        for fake in fakes:
            (exp_id, fake_id, class_id, chip_pathbase, cam_pathbase, camera, reduction, dvodb, workdir) = fake
            outroot = '%s/%s/%s.fk.%d' % (workdir, exp_id, exp_id, fake_id)
            arguments = 'Arguments = %s' % GlobalConstants.FAKE_IMFILE
            arguments = '%s --exp_id %d' % (arguments, exp_id)
            arguments = '%s --fake_id %d' % (arguments, fake_id)
            arguments = '%s --class_id %s' % (arguments, class_id)
            arguments = '%s --chiproot=%s' % (arguments, chip_pathbase)
            arguments = '%s --camroot=%s' % (arguments, cam_pathbase)
            arguments = '%s --camera %s' % (arguments, camera)
            arguments = '%s --outroot %s' % (arguments, outroot)
            if reduction is not None and reduction != 'NULL':
                arguments = '%s --reduction %s' % (arguments, reduction)
            if dvodb is not None and dvodb != 'NULL':
                print 'dvodb is defined but I won\'t use it'
            #     arguments = '%s --dvodb %s' % (arguments, dvodb)
            output.write('%s\n' % arguments)
            output.write('Queue\n')
            output.write('\n')
        if len(fakes) == 0:
            arguments = "Arguments = echo Nothing to do for stage %s" % stage_name
            output.write('%s\n' % arguments)
            output.write('Queue\n')
            output.write('\n')
        output.close()

    def build_fake_revert_jobs(self, stage_name):
        """Revert faulty fakes if any
        """
        query = """
DELETE FROM fakeProcessedImfile
USING fakeProcessedImfile, fakeRun, camRun, chipRun, rawExp
WHERE
    fakeProcessedImfile.fake_id = fakeRun.fake_id
    AND fakeRun.cam_id = camRun.cam_id
    AND camRun.chip_id = chipRun.chip_id
    AND chipRun.exp_id = rawExp.exp_id
    AND fakeProcessedImfile.fault != 0
    AND fakeRun.label = '%s'
    AND chipRun.exp_id = %d
""" % (self.label, self.get_exposure_id(self.exposure_name))
        self.multiple_query(query)
        self.build_new_fake_jobs(stage_name)

    def advance_fake(self):
        """Last phase (C050) in fake stage:
        * 
        """
        jobs_filename = '%s/C050.jobs' % (self.fake_directory)
        print "Generating Condor jobs file [%s] for processing of a fake (stage C050)" % (jobs_filename)
        output = open(jobs_filename, 'w')
        output.write('Executable = /home/panstarrs/ippdor/local/bin/encapsulate_fake.sh\n')
        output.write('Universe = vanilla\n')
        output.write('Output = %s/out.%s.%s.fake_C050\n' % (GlobalConstants.NFS_TMP_DIR,
                                                            self.label, 
                                                            self.exposure_name))
        output.write('Error = %s/err.%s.%s.fake_C050\n' % (GlobalConstants.NFS_TMP_DIR,
                                                           self.label, 
                                                           self.exposure_name))
        output.write('Log = %s/%s_fake_C050.log\n' % (GlobalConstants.LOCAL_TMP_DIR,
                                                      self.exposure_name))
        output.write('Requirements = %s\n' % FakeConstants.REQUIREMENTS)
        output.write('Notification = Error\n')
        output.write('\n')
        output.write('getenv = True\n')
        output.write('\n')
        arguments = '%s -advanceexp' % GlobalConstants.FAKETOOL
        arguments = '%s -fake_id %d -label %s' % (arguments,
                                                  self.get_fake_id(self.exposure_name, 
                                                                   self.label), 
                                                  self.label)
        output.write('Arguments = %s\n' % arguments)
        output.write('Queue\n')
        output.write('\n')
        output.close()

    def build_fake_dag(self):
        """Build the full DAG file for the fake (aka C) stage
        """
        dag_name = '%s/fake.dag' % (self.fake_directory)
        output = open(dag_name, 'w')
        output.write('# Generated DAG\n')
        output.write('JOB\tC010\t%s/C010.jobs\n' % self.fake_directory)
        output.write('SCRIPT POST C010 %s C020 %s %s\n' % (FakeManager.SCRIPT_NAME, 
                                                           self.label, self.exposure_name))
        output.write('JOB\tC020\t%s/C020.jobs\n' % self.fake_directory)
        output.write('SCRIPT POST C020 %s C030 %s %s\n' % (FakeManager.SCRIPT_NAME, 
                                                           self.label, self.exposure_name))
        output.write('JOB\tC030\t%s/C030.jobs\n' % self.fake_directory)
        output.write('SCRIPT POST C030 %s C040 %s %s\n' % (FakeManager.SCRIPT_NAME, 
                                                           self.label, self.exposure_name))
        output.write('JOB\tC040\t%s/C040.jobs\n' % self.fake_directory)
        output.write('SCRIPT POST C040 %s C050 %s %s\n' % (FakeManager.SCRIPT_NAME, 
                                                           self.label, self.exposure_name))
        output.write('JOB\tC050\t%s/C050.jobs\n' % self.fake_directory)
        output.write('\n')
        output.write('PARENT C010 CHILD C020\n')
        output.write('PARENT C020 CHILD C030\n')
        output.write('PARENT C030 CHILD C040\n')
        output.write('PARENT C040 CHILD C050\n')
        output.write('\n')
        output.close()
        return dag_name

#################################################################
if __name__ == '__main__':
    import sys
    print '<Error>: Use %s' % FakeManager.SCRIPT_NAME
    sys.exit(1)
