import filecmp
import os
import sys

import smtk
if smtk.wrappingProtocol() == 'pybind11':
    import smtk.attribute
    import smtk.io
    import smtk.model
    import smtk.resource
    import smtk.bridge.exodus

# Add path to ACE3P.py script
abs_path = os.path.abspath(__file__)
abs_dir = os.path.dirname(abs_path)
module_dir = os.path.join(abs_dir, os.pardir, os.pardir, os.pardir, os.pardir)
sys.path.append(module_dir)
import ACE3P

# Hard-coded to exodus model-session
SESSION_TYPE = 'exodus'

#----------------------------------------------------------------------
def load_smtk_model(model_manager, session_type, smtk_file):
  '''Imports and returns smtk model.

  Application should check validity
  '''
  print 'loading model file'
  mgr = smtk.model.Manager.create()
  sess = model_manager.createSession(session_type)
  sess.assignDefaultName()

  op = sess.op("load smtk model")
  #print 'op', op
  op.findFile("filename", smtk.attribute.ALL_CHILDREN).setValue(0, smtk_file)
  #print 'able to operate?', op.ableToOperate()
  result = op.operate()

  outcome = result.findInt('outcome').value(0)
  print 'outcome ok?', outcome == smtk.model.OPERATION_SUCCEEDED
  model = result.findModelEntity('created').value(0)
  print 'model valid?', model.isValid()
  return model

#----------------------------------------------------------------------
def load_resources(model_manager, resource_file):
  '''Reads and returns smtk.common.ResourceSet
  '''
  print 'loading resource file'
  resources = smtk.resource.Set()
  reader = smtk.io.ResourceSetReader(model_manager)
  logger = smtk.io.Logger()

  hasErrors = reader.readFile(resource_file, resources, logger)
  if hasErrors:
      print "Reader has errors:"
      print logger.convertToString()

  return resources

#----------------------------------------------------------------------
def load_attributes(model_manager, att_file):
  '''Reads and returns attribute system
  '''
  print 'loading attribute file'
  att_system = smtk.attribute.System()
  att_system.setRefModelManager(model_manager)
  reader = smtk.io.AttributeReader()
  logger = smtk.io.Logger()
  read_err = reader.read(att_system, att_file, logger)
  print 'read ok?', not read_err
  return att_system

#----------------------------------------------------------------------
def compare_files(test_file, baseline_file):
  '''
  '''
  if not os.path.exists(test_file):
    print 'Output file not found:', test_file
    return

  if not os.path.exists(baseline_file):
    print 'Baseline file not found:', baseline_file
    return

  match = filecmp.cmp(test_file, baseline_file)
  print 'Output file match baseline?', match

  if not match:
    print
    print 'Files do NOT MATCH'
    print ' ', test_file
    print ' ', baseline_file

#----------------------------------------------------------------------
class MockExportSpec:
  '''
  '''
  def __init__(self, sim_atts, export_atts=None):
    self.sim_atts = sim_atts
    self.export_atts = export_atts
    self.logger = smtk.io.Logger()

  def getSimulationAttributes(self):
    return self.sim_atts

  def getExportAttributes(self):
    return self.export_atts

  def getLogger(self):
    return self.logger

#----------------------------------------------------------------------
if __name__ == '__main__':
  if len(sys.argv) < 4:
    print
    print 'Standalone writer test'
    print 'Usage: python testwriter.py crf_file analysis_type',
    print 'smtk_model_file  [baseline_file]'
    print
    print 'Supported analysis types: {Omega3P, S3P, T3P}'
    print
    sys.exit(-1)

  # Load model first
  model_manager = smtk.model.Manager.create()

  model_file = sys.argv[3]
  model = load_smtk_model(model_manager, SESSION_TYPE, model_file)
  if not model.isValid():
    print 'ERROR loading model file', model_path
    sys.exit(-1)

  # Load resource file
  crf_file = sys.argv[1]
  resource_set = load_resources(model_manager, crf_file)

  # Initialize simuation attributes
  simbuilder_resource = resource_set.get('simbuilder')
  if smtk.wrappingProtocol() == 'shiboken':
    sim_atts = smtk.attribute.System.CastTo(simbuilder_resource)
  else:
    sim_atts = simbuilder_resource
  #print 'sim_atts', sim_atts

  export_resource = resource_set.get('export')
  if smtk.wrappingProtocol() == 'shiboken':
    export_atts = smtk.attribute.System.CastTo(export_resource)
  else:
    export_atts = export_resource
  #print 'export_atts', export_atts

  # Initialize export attributes
  export_spec_att = None
  att_list = export_atts.findAttributes('ExportSpec')
  if att_list:
    export_spec_att = att_list[0]
  else:
    export_spec_defn = export_atts.findDefinition('ExportSpec')
    export_spec_att = export_atts.createAttribute(
      'ExportSpec', export_spec_defn)

  # Set analysis type
  analysis = sys.argv[2]
  print 'Writing analysis type %s' % analysis
  analysis_item = export_spec_att.findString('Analysis')
  analysis_item.setValue(0, analysis)

  # Set output file
  input_path = os.path.abspath(crf_file)
  output_dir = os.path.dirname(input_path)
  dir_item = export_spec_att.findDirectory('OutputFolder')
  dir_item.setValue(0, output_dir)

  root,ext = os.path.splitext(crf_file)
  prefix_item = export_spec_att.findString('OutputFilePrefix')
  prefix_item.setValue(0, root)

  # Initialize MockExportSpec and run export script
  export_spec = MockExportSpec(sim_atts, export_atts)
  completed = ACE3P.ExportCMB(export_spec)

  # If baseline file specified, compare results
  if completed and len(sys.argv) > 4:
    baseline_file = sys.argv[4]
    root,ext = os.path.splitext(input_path)
    output_path = '%s.t3p' % root
    compare_files(output_path, baseline_file)

  print 'finis'
