#!/usr/bin/env jython

#
# The main loading program for ippToPsps. See usage below.
#

import time
import sys
import os
import math
import logging.config

from ipptopsps import IppToPsps
from gpc1db import Gpc1Db
from datastore import Datastore
from dvoobjects import DvoObjects
from batch import Batch
from scratchdb import ScratchDb

'''
Queue class
'''
class Queue(IppToPsps):

    '''
    Constructor
    '''
    def __init__(self, argv):
        super(Queue, self).__init__(argv)

        # print "inited ipptopsps"

        # create various objects
        self.gpc1Db = Gpc1Db(self.logger, self.config)
        # print "connect to gpc1"

        self.datastore = Datastore(self.logger, self.skychunk, self.ippToPspsDb)

        print "made datastore"

        # connect to scratch database
        self.scratchDb = ScratchDb(self.logger, self.config)

        print "connect to scratchdb"

        try:
            print "why doesn't this work"
            self.dvoObjects = DvoObjects(self.logger, self.config, self.skychunk, self.ippToPspsDb, self.scratchDb)
        except:
            self.exitProgram("Unable to create instance of DvoObject")
            raise

        print "got objects"

        self.skychunk.printAll()

        if len(argv) > 2: self.parsePollTimeArg(sys.argv[2])

    '''
    Main processing loop.
    Tiled area is defined in 'skychunk' and looks for available stage_ids for each tile and writes them to ippToPsps database ready for processing
    by one or more loading clients that may be running on any host
    '''
    def run(self):
        print "here"
        # this outer while loop simply waits a few minutes then starts queuing again (as more stuff may appear in DVO over time)
        while True:

      #      self.ippToPspsDb.removeAllBoxes()
            print "remove boxes" 
            # queue up batches that are processed but not loaded to datastore
            for batchType in self.skychunk.batchTypes: 
                self.logger.infoPair("BatchType",batchType)
                #self.logger.infoTitle("Previous failed datastore loads")
                #self.publishAnyUnpublishedBatches(batchType)

                # get totals for whole area to check if there is anything to do
                processedIDs = self.ippToPspsDb.getProcessedIDs(batchType)
                print "got processed ids"
                consistantlyFailedIDs = self.ippToPspsDb.getConsistentlyFailedIDs(batchType)
                print "got here"
                # for object batches, get full list of stuff from Dvo
                # XXX : need to fix 'dvo.setSkyArea' or this may not return the full list for a parallel dvo
            #for object-like batches, info comes from dvo
                if (batchType == "OB" or batchType =="DO" or batchType =="FO"):
                    self.dvoObjects.setSkyArea(
                            self.skychunk.minRa,
                            self.skychunk.maxRa,
                            self.skychunk.minDec,
                            self.skychunk.maxDec)
                    rows = self.dvoObjects.allPopulatedRegionInfo
                    self.dvoObjects.printSummary()

                # for other batches, info comes from gpc1 database
                else:
                    rows = self.gpc1Db.getItemsInThisDVODbForThisStage(
                            self.skychunk.dvoLabel, 
                            batchType, 
                            self.skychunk.minRa, 
                            self.skychunk.maxRa, 
                            self.skychunk.minDec, 
                            self.skychunk.maxDec,
                            self.skychunk.trange_start,
                            self.skychunk.trange_end)

                # EAM TEST I/O
                self.logger.infoPair("received rows from db:", len(rows))

                # first report total stuff
                allIDs = []
                for row in rows:
                    try: allIDs.append(row[0])
                    except: pass

                ids = list(set(allIDs) - set(processedIDs) - set(consistantlyFailedIDs))
                self.logger.infoPair("All unprocessed items", "%d" % len(ids))

                # now trim full list down to only pending stuff
                pending = [[], [], []]
                for row in rows:
                    try:
                        findId = row[0]
                    except: continue
                    if findId in allIDs: pending.append([row[0], row[1], row[2]])

                # store all items in temp table
                self.logger.infoPair("Inserting all pending items into", "ippToPsps database")
                self.ippToPspsDb.storeAllItemsInDvodb(pending, self.skychunk.dvoLabel, batchType)

                self.logger.info("+-------------+-------------+-------------+-------------+")

            self.checkClientStatus()
            if not self.waitForPollTime(): break

    '''
    Overrides base-class version
    '''
    def printUsage(self):
        super(Queue, self).printUsage("[<repeat time in hours>]")


'''
Start of program.
'''
try:
    queue = Queue(sys.argv)
    queue.run()
    queue.exitProgram("completed")
except: pass

