from orangescape.model.engine.execution.ProcessEngine import ProcessNode
from orangescape.model.engine.execution.ProcessUtil import getInputportByParamName
import logging

class AppendProcessNode(ProcessNode):

    def enter(self):
        chkParameter = self.args.get('empty-Src-Params')
        chkMappingParameter = self.args.get('Check-Mapping')

        referenceCell = self.args.get('ReferenceCell')
        if not referenceCell:
            logging.debug('Specified input ports...')
            for ipPort in self.activityDefinition.getInputportMetadataList():
                logging.debug('Param :%s'%(ipPort.getParamName()))
            logging.debug('Resolved args :%s'%(self.args))
            errMsg = 'Reference cell is not specified in the input port to process the append command for the sheet %s'%(self.sheet.getSheetMetadata().getSheetName())
            raise Exception(errMsg)

        metadata = self.sheet.getSheetMetadata()
        childMetadata = referenceCell.getSheetMetadata()
        if referenceCell.getReferredSheetMetadata().getSheetId()!=metadata.getSheetId():
            msg = "Sheet %s don't have one-to-many relation ship with sheet %s with the connect cell %s"%(metadata.getSheetName(), childMetadata.getSheetName(), referenceCell)
            raise Exception(msg)

        cellValues = dict()
        srcSheetNone = dict()

        if chkMappingParameter:
            for opPort in self.activityDefinition.getOutputportMetadataList():
                if opPort.getCellMetadata():
                    if self.args.has_key(opPort.getParamName()):
                        value = self.args[opPort.getParamName()]
                        cellValues[opPort.getCellMetadata().getCellName()] = value
                        ipPort = getInputportByParamName(self.activityDefinition, opPort.getParamName())
                        if ipPort:
                            cell = ipPort.getCellMetadata()

                            if not cell and ipPort.getFormulaList():
                                """This is ugly code should be removed after fixing the cell selection in params in command
                                Currently cell selections are handled using formula.
                                """
                                formula = ipPort.getFormulaList()[0]
                                rootNode = formula.getNodeList()[0]
                                cell = rootNode.getCellMetadata()

                            if cell and not cell.isFormula() and not cell.isSystemCell():
                                srcSheetNone[cell.getCellName()] = None
                    else:
                        logging.warn('output params mismatching, %s not found in params for the cell %s or the value might be None'%(opPort.getParamName(), opPort.getCellMetadata().getCellName()))
                else:
                    logging.warn('LHS Ouput Params value in Append might be None')

        else:
            for cell in metadata.getCellMetadataList():
                cellName = cell.getCellName()
                if not cell.isSystemCell():
                    if childMetadata.getPublicCellMetadataDict().__contains__(cellName) and not childMetadata.getPublicCellMetadata(cellName).isSystemCell():
                        cellValues[cellName] = self.sheet.get(cell)
                        if not cell.isFormula():
                            srcSheetNone[cellName] = None

        if logging.getLogger().level == logging.DEBUG:
            logging.debug('Appending %s under the model %s.%s for the instance %s with the values %s'%(childMetadata.getSheetName(), metadata.getSheetName(), referenceCell.getCellName(), self.sheet.getSheetName(), cellValues))
        sheet = self.component.create(self.sheet, referenceCell, cellValues)

        if chkParameter:
            logging.info('Updating source value to None %s' %(srcSheetNone))
            self.component.update(self.sheet, srcSheetNone)
