import os,sys
try:
  from CCP4ReportParser import *
except:
  execfile(os.path.join(os.environ['CCP4I2_TOP'],'bin/ccp4i2.pythonrc'))
  from CCP4ReportParser import *

import pointless_report
import aimless_report
import ctruncate_report

class import_merged_report(Report):
  TASKNAME = 'import_merged'
  RUNNING = True

  #def __init__(self,xmlnode=None,jobInfo={},jobStatus=None,**kw):
  def __init__(self,xmlnode=None,jobInfo={},**kw):
    Report. __init__(self,xmlnode=xmlnode,jobInfo=jobInfo,**kw)
    ##self.aimlessreport = aimless_pipe_report.aimless_pipe_report(xmlnode=xmlnode,jobStatus='nooutput')

    if kw.get('jobStatus',None) is not None and kw.get('jobStatus').lower() == 'nooutput':
      return
    elif kw.get('jobStatus',None) is not None and kw.get('jobStatus').lower() == 'running':
      self.runningReport()
    else:
      self.finalReport()


  # . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . . 
  def runningReport(self, parent=None):
    if parent is None: parent = self

    status, text = self.importReport()

    # what is it doing now?
    if status == "EMPTY":
      return
    elif status == "IMPORTING":
      parent.addText(text="File import is running",
                     style='font-weight:bold; font-size:150%; color:red;')
    elif status == "DRPIPE_RUNNING":
      parent.addText(text="Data reduction pipeline is running to generate statistcs",
                     style='font-weight:bold; font-size:150%; color:red;')
    elif status == "FINISHED":  # shouldn't happen
      parent.addText(text="Data reduction pipeline has finished",
                     style='font-weight:bold; font-size:150%; color:red;')

    for line in text:
      parent.append(line)

    parent.addText(text="NB data from the original file are kept for use in downstream processing",
                   style='font-weight:bold; font-size:120%; color:blue;')

    # FreeR fail?
    self.freeRmessage(parent)

  # . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . . 
  def importReport(self):
    '''
    Format stuff from import step IMPORT_LOG
    Returns status, messagelist:
    status is
      "EMPTY"     nothing there
      "IMPORTING" running the import step
      "DRPIPE_RUNNING" running DR pipeline, aimless_pipe
      "FINISHED"  finished
    '''

    status = "EMPTY"
    if not self.xmlnode.haspath("IMPORT_LOG"): return status, []

    text = []
    self.importxml = self.xmlnode.xpath0("IMPORT_LOG") # all information from import_merged task

    # what is it doing now?
    if self.xmlnode.haspath("AIMLESS_PIPE"):
      status = "FINISHED"
      message1 = 'file read'
    elif self.importxml.haspath("DRPIPE_RUNNING"):
      # this may be there after finishing, but is overriden by AIMLESS_PIPE above
      status = "DRPIPE_RUNNING"
      message1 = 'file read'
    else:
      status = "IMPORTING"
      message1 = 'file reading'


    merged = 'Unmerged' # shouldn't ever be this, always merged!
    if self.importxml.select('merged') == 'True': merged = 'Merged'

    # possible formats:
    #   'mtz', 'mmcif', 'shelx', 'sca'
    fformat = self.importxml.select('fileformat')
    message = ''
    if fformat == 'mtz':
      columnlabels = self.importxml.select('columnlabels')
      message = 'Merged MTZ ' + message1
    elif fformat == 'mmcif':
      message = 'mmCIF ' + message1
    elif fformat == 'shelx':
      message = 'ShelX ' + message1
    elif fformat == 'sca':
      message = 'Merged Scalepack ' + message1
      
    text.append(message)

    if fformat == 'mtz' and columnlabels is not None:
      message = 'Column labels selected: '+columnlabels
      text.append(message)

      IorFtype = "Unknown"
      if self.importxml.haspath("IorFtype"):
        IorFtype = self.importxml.select("IorFtype")      
        if IorFtype == "Unknown":
          message = "Imported values are of unknown type, maybe intensities or amplitudes"
        elif IorFtype == "Amplitude":
          message = \
                  "Imported values are amplitudes, and will be squared for statistical analysis only"
        elif IorFtype == "Intensity":
          message = "Imported values are intensities"
        text.append(message)
          
    return status, text
  
  # . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . . 
  # FreeR fail?
  def freeRmessage(self, parent=None):
    '''
    Check whether a FreeR set was created
    Two XML blocks, both may occur twice:
      a) newFreeR, == True new set, False completing or completed
      b) FreeRfailed == True if failed and tried again
         == Again if failed finally
    Cases:
     1) Completed existing FreeR succesfully on 1st attempt
        newFreeR == "False", no FreeRfailed block
     2) New FreeR set on first attempt
        newFreeR == "True", no FreeRfailed block
     3) Complete failed on 1st attempt, running 2nd attempt to make new set
         newFreeR == "False", FreeRfailed == "True"
     4) Complete failed on 1st attempt, 2nd attempt to make new set succeeded
        two newFreeR == "False", "True", FreeRfailed == "True"
     5) Complete failed on 1st attempt, 2nd attempt to make new set failes
        two newFreeR == "False", "True", two FreeRfailed == "True", Again
        Probably should not occur
    '''

    headlines = []
    text = []

    frfs = []
    nfrs = []
    if self.importxml.haspath('FreeRfailed'):
      freerfailed = self.importxml.xpath('FreeRfailed')
      for frf in freerfailed:
        frfs.append(frf.text)
      
    if self.importxml.haspath('newFreeR'):
      newfreer = self.importxml.xpath('newFreeR')
      for nfr in newfreer:
        nfrs.append(nfr.text)
                    
    if len(frfs) == 2:
      # Case 5, shouldn't happen
      if (frfs[0] == 'True') and (frfs[0] == 'Again'):
        headlines.append("NOTE WARNING: completely failed to generate a FreeR set")
      else:
        headlines.append("SCRIPT ERROR: two values of FreeRfailed "+
                         frfs[0]+", "+frfs[1])
    elif len(frfs) == 1:
      # Case 3 or 4
      if len(nfrs) == 1:
        # Case 3, should be "False", during rerun
        if nfrs[0] == "False":
          headlines.append("WARNING: the imported FreeR set could not be extended, because all input values are the same")
          headlines.append("Generating a new FreeR set instead")
        else:
          headlines.append("SCRIPT ERROR: wrong value of newFreeR: "+nfrs[0])
      else:
        # Case 4, newFreeR should be "False", "True"
        if (nfrs[0] == "False") and (nfrs[1] == "True"):
          headlines.append("WARNING: the imported FreeR set could not be extended, because all input values are the same")
          headlines.append("A new FreeR set has been generated instead")
        else:
          headlines.append("SCRIPT ERROR: wrong values of newFreeR: "+
                           nfrs[0]+","+nfrs[1])
    else:
      # Success, case 1 or 2
      if len(nfrs) > 0:
        if nfrs[0] == 'False':
          text.append("The imported FreeR set has been copied and completed")
        else:
          text.append("A new FreeR set has been constructed")

    if len(headlines) > 0:
      for line in headlines:
        parent.append('<br/>')
        parent.addText(text=line,
                       style='font-weight:bold; font-size:120%; color:red;')
      parent.append('<br/>')

    if len(text) > 0:
      for line in text:
        parent.append(line)
    
  # . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . . 

  def finalReport(self, parent=None):
    # Adapted from aimless_pipe_report  

    if parent is None: parent = self

    topDiv = parent.addDiv(style="border-width: 1px; border-color: black;clear:both; margin:0px; padding:0px;")

    status, text = self.importReport()

    # what is it doing now?
    if not status == "FINISHED": return

    topDiv.addText(text="Import of merged data",
                     style='font-weight:bold; font-size:150%; color:red;')
    for line in text:
      topDiv.append(line)

    topDiv.addText(text="NB data from the original file are kept for use in downstream processing",
                   style='font-weight:bold; font-size:120%; color:blue;')

    text = []
    text.append("The report below from the data reduction pipeline is purely for analysis")
    text.append("No files from this will be used in further jobs")
    for line in text:
      topDiv.append(line)

    self.freeRmessage(topDiv)

    topDiv.append('<br/>')
    topDiv.addText(text="Report from data reduction, for analysis only",
                     style='font-weight:bold; font-size:150%; color:red;')
      
    # Instantiate aimless and pointless and ctruncate reports from which to cherry pick
    # The nooutput flag makes sure thay don't do anything

    drpipelinexml = self.xmlnode.xpath0("AIMLESS_PIPE")
    
    #  1) POINTLESS
    pointlessxml = drpipelinexml.xpath0("POINTLESS")
    if pointlessxml != None:
      self.pointlessreport = \
          pointless_report.pointless_report(xmlnode=pointlessxml, jobStatus='nooutput')
        
    #  2) AIMLESS
    aimlessxml = drpipelinexml.xpath0("AIMLESS")
    if (aimlessxml != None):
      self.aimlessreport = \
        aimless_report.aimless_report(xmlnode=aimlessxml, jobStatus='nooutput')

    #  3) CTRUNCATE
    ctruncatexmlsnode = drpipelinexml.xpath0("CTRUNCATES")
    ctruncatexmlnodelist = None
    self.ctruncatereports = None
    if ctruncatexmlsnode != None:
      ctruncatexmlnodelist = ctruncatexmlsnode.xpath("CTRUNCATE")
          
    if (ctruncatexmlnodelist != None):
      self.ctruncatereports = []
      for ctruncatexmlnode in ctruncatexmlnodelist:
        self.ctruncatereports.append(
          ctruncate_report.ctruncate_report(xmlnode=ctruncatexmlnode, jobStatus='nooutput') )
            
    # . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . . 

    # Error messages, if any
    errorspresent = False
    if pointlessxml != None:
      if self.pointlessreport.isFatalError():
        errorspresent = True
        
      if errorspresent:
        errorDiv = parent.addDiv(style="border-width: 1px; border-color: black;clear:both; margin:0px; padding:0px;")
        errorDiv.append('ERRORS')
        self.pointlessreport.Errors(errorDiv)   #  report any fatal errors
        
    # . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . . 
    #   Overall summaries
    self.numberofdatasets = 1   # always = 1 here, I hope
    # if (aimlessxml != None):
    #    self.numberofdatasets = self.aimlessreport.numberOfDatasets()
      
    # . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . . 
    # Summary of summaries
    summaryDiv = parent.addDiv(\
           style="width:100%;border-width: 1px; border-color: black; clear:both; margin:0px; padding:0px;")
    summaryfold = summaryDiv.addFold(label='Key summary', brief='Headline',
                                     initiallyOpen=True)
    if pointlessxml != None:
      fail = self.pointlessreport.Errors(summaryfold)   #  report any fatal errors
      if fail:
        return

    self.pointlessreport.keyTextMerged(summaryfold)

    if (aimlessxml != None):
      self.aimlessreport.keyTextMerged(summaryfold)

    # ctruncate
    if self.ctruncatereports != None:
      self.ctruncatereports[0].keyText(summaryfold)

    # . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . .  . . . . 
    # Main summary
    overallsummaryDiv = parent.addDiv(\
         style="width:100%;border-width: 1px; border-color: black; clear:both; margin:0px; padding:0px;")
    overallfold = overallsummaryDiv.addFold(label='Overall summary',
                                                brief='Summary',initiallyOpen=True)
      
    # Put the key messages about spacegroup and resolution at the very top
    headlineDiv = overallfold.addDiv(style="border-width: 1px; border-color: black; clear:both; margin:0px; padding:5px;")
    leftDiv = headlineDiv.addDiv(style="width:49%;float:left;text-align:center;margin:0px; padding:0px; line-height:100%; font-size:100%;border:0px;")

    # not usually anything useful from Pointless
    #if pointlessxml != None:
    #  self.addPointlessSummaryMerged(leftDiv)

    if (aimlessxml != None):
      # Aimless summary
      statsDiv = headlineDiv.addDiv(style="width:46%;float:left;text-align:center;margin:0px; padding:10px;border:3px solid black;")
      self.addAimlessSummaryMerged(statsDiv)

    #  Aimless resolution graphs in left div
    if (aimlessxml != None):
      # Put the key graphs that report on data quality and image-to-image quality at the top
      leftDiv.addText(text='Analysis as a function of resolution',style='font-size:130%;font-weight:bold;')
      leftDiv.append('<br/>')
      self.aimlessreport.ByResolutionGraphsMerged(leftDiv)

    if self.ctruncatereports != None:
      self.addTruncateWilson(leftDiv)

    # Truncate L-test next
    if self.ctruncatereports != None:
      headerDiv = overallsummaryDiv.addDiv(style="width:100%; border-width: 1px; border-color: black; clear:both; margin:0px; padding:0px;text-align:center")
      headerDiv.append('<br/>')
      
      headerDiv.addText(text='Graphs for detecting twinning etc, more details below',
                        style='width:100%;text-align:left;font-weight: bold; font-size:130%;')

      twinned = self.ctruncatereports[0].addWarningTwin(headerDiv,check=True)
      headerDiv.append('<br/>')
      if twinned:
        headerDiv.addText(text='This dataset is probably twinned',
                          style='width:100%;text-align:left;font-weight: bold; font-style:italic; font-size:130%;color:red;')
      else:
        headerDiv.addText(text='This dataset is probably NOT twinned',
                            style='width:100%;text-align:left;font-weight: bold; font-style:italic; font-size:130%;color:green;')

      leftDiv = overallsummaryDiv.addDiv(style="width:49%;float:left;text-align:center;margin:0px; padding:0px; line-height:100%; font-size:100%;border:0px;")
      rightDiv =overallsummaryDiv.addDiv(style="width:46%;float:right;text-align:center;margin:0px; padding:10px;border:1px solid black;")

      self.addTruncateLtest(leftDiv)
      for ctruncatereport in self.ctruncatereports:
        ctruncate_report.ctruncate_report(xmlnode=ctruncatereport, jobStatus='nooutput')
        ctruncatereport.acentricMoments(rightDiv)

        truncateDiv = parent.addDiv(style="border-width: 1px; border-color: black; clear:both; margin:0px; padding:0px;")
        fold = truncateDiv.addFold(label="Intensity statistics: twinning tNCS etc",brief='Istats')
        self.addCtruncateReports(fold)


  # . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  def addTruncateLtest(self, parent=None):
    LtestDiv = parent.addDiv(
      style="text-align:center;margin:0px auto; padding:3px; border:1px solid black;")
    LtestDiv.addText(text='L-test for twinning',style="font-weight:bold; font-size:130%;")
    self.ctruncatereports[0].CtruncateLtest(LtestDiv)

  # . . . . . . . . . . . . . . . . . . . . . . . . . . . .
  def addTruncateWilson(self, parent=None):
    WilsonDiv = parent.addDiv(
      style="text-align:center;margin:0px auto; padding:3px; border:1px solid black;")
    WilsonDiv.addText(text='Wilson plot',style="font-weight:bold; font-size:130%;")
    self.ctruncatereports[0].CtruncateWilson(WilsonDiv)

  # - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  def addAimlessSummaryMerged(self, parent=None):
    aHeaderDiv = parent.addDiv(
      style="clear:both;font-weight:bold; font-size:130%;margin:0px;padding:0px;")
    aHeaderDiv.append('Data internal consistency statistics')
    self.aimlessreport.ResultTableMerged(parent)


  # - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  def addCtruncateReports(self, parent=None):
    for ctruncatereport in self.ctruncatereports:
      ctruncate_report.ctruncate_report(xmlnode=ctruncatereport, jobStatus='nooutput')
      ctruncatereport.addCtruncateReport(parent)
      

############################################################################
if __name__ == "__main__":

  report = import_merged_report(xmlFile = sys.argv[1],jobStatus="Finished" )
  tree= report.as_etree()
  #print etree.tostring(tree,pretty_print=True)
  report.as_html_file(fileName='./test-import.html')
  if len(report.errorReport())>0: print 'ERRORS:',r.errorReport()

