#!/usr/bin/env jython

from subprocess import call, PIPE, Popen
import tempfile
from xml.etree.ElementTree import ElementTree, Element, tostring
import re
import sys
import time
import traceback
import logging.config

from ipptopsps import IppToPsps
from batch import Batch
from datastore import Datastore
from dxlayer import DXLayer

'''
Cleanup class
'''
class Cleanup(IppToPsps):

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

        self.datastore = Datastore(self.logger, self.config, self.ippToPspsDb)
        self.dxlayer = DXLayer(self.logger)
        if len(argv) > 2: self.parsePollTimeArg(sys.argv[2]) 


    '''
    Runs...
    '''
    def run(self):

        if self.SECONDS: self.logger.infoPair("Performing clean-up every", "%f hours" % (self.SECONDS/60.0/60.0))
        while True:

            self.logger.infoSeparator()
            self.logger.infoPair("Config", self.config.name)
            self.config.printDeletionPolicy()
            self.clean("IN")
            self.clean("P2")
            self.clean("ST")
            self.clean("OB")

            self.checkClientStatus()
            if not self.waitForPollTime(): break
   
    '''
    Reports results of cleanup for this set of IDs 
    '''
    def reportResults(self, name, ids, success):

        if len(ids) > 0:
            self.logger.infoSeparator()
            self.logger.infoPair("Removed from " + name, "%d of %d" % (success, len(ids)))
    

    '''
    Finds stuff to delete for this batch type, then:

    - removes from the datastore
    - deletes from local disk
    - deletes files from DXLayer

    '''
    def clean(self, batchType):

        self.logger.infoSeparator()
        self.logger.infoTitle("Cleaning up batch type %s" % batchType)

        loadedDatastoreIDs = self.ippToPspsDb.getLoadedToODMButNotDeletedFromDatastore(batchType)
        deleteFromDxLayerIDs = self.ippToPspsDb.getLoadedToODMButNotDeletedFromDXLayer(batchType)
        mergedLocalIDs = self.ippToPspsDb.getMergedButNotDeletedFromLocalDisk(batchType)

        purgedDatastoreIDs = self.ippToPspsDb.getPurgedButNotDeletedFromDatastore(batchType)
        purgedLocalIDs = self.ippToPspsDb.getPurgedButNotDeletedFromLocalDisk(batchType)

        deleteFromDatastoreIDs = loadedDatastoreIDs + purgedDatastoreIDs
        deleteFromLocalIDs = mergedLocalIDs + purgedLocalIDs

        # report to log what we are going to do
        self.logger.infoPair("To delete from datastore", "%d" % len(deleteFromDatastoreIDs))
        self.logger.infoPair("To delete from DXLayer", "%d" % len(deleteFromDxLayerIDs))
        self.logger.infoPair("To delete from local disk", "%d" % len(deleteFromLocalIDs))
    
        # delete stuff from local disk
        if self.config.deleteLocal:
            count = 0
            for id in deleteFromLocalIDs:
        
                if Batch.deleteFromDisk(self.logger, self.config.basePath, batchType, self.config.dvoLabel, id):
                    self.ippToPspsDb.updateDeletedLocal(id, 1)
                    count = count + 1
    
            self.reportResults("local disk", deleteFromLocalIDs, count) 
    
        # remove stuff from datastore
        if self.config.deleteDatastore:
            count = 0
            for id in deleteFromDatastoreIDs:
        
                batchName = Batch.getNameFromID(id)
    
                if self.datastore.remove(batchName):
                    count = count + 1
    
            self.reportResults("datastore", deleteFromDatastoreIDs, count) 
        
        # remove stuff from DXLayer
        if self.config.deleteDxLayer:
            count = 0
            for id in deleteFromDxLayerIDs:
        
                if self.dxlayer.deleteBatch(id):
                    self.ippToPspsDb.updateDeletedDxlayer(id, 1)
                    count = count + 1
    
            self.reportResults("DXLayer", deleteFromDxLayerIDs, count) 
       
    '''
    Overrides base-class version
    '''
    def printUsage(self):
        super(Cleanup, self).printUsage("[<poll time in hours>]")


'''
Start of program
'''
try:
    cleanup = Cleanup(sys.argv)
    cleanup.run()
    cleanup.exitProgram("completed")
except Exception, e:
    print str(e)
    traceback.print_exc()
