import imp
import os
import sys

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

# Add path to Truchas.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)
sys.path.append(module_dir)
import Truchas as truchas

# Currently hard-coded to exodus models only
SESSION_TYPE = 'exodus'

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

  Application should check validity
  '''
  print 'importing model file'
  sess = model_manager.createSession(session_type)
  sess.assignDefaultName()

  op = sess.op("import smtk model")
  #print 'op', op
  if 'shiboken' == smtk.wrappingProtocol():
    op.findFile("filename", smtk.attribute.ALL_CHILDREN).setValue(0, smtk_file)
  else:
    op.findFile('filename').setValue(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.common.ResourceSet()
  reader = smtk.io.ResourceSetReader()
  logger = smtk.io.Logger()

  #has_errors = reader.readFile(resource_file, resources, logger)
  with open(resource_file) as instream:
    content = instream.read()

    simatts = smtk.attribute.System()
    simatts.setRefModelManager(model_manager)
    resource_map = {'simbuilder': simatts}
    has_errors = reader.readString(content, resources, logger, True, resource_map)
    if has_errors:
        print "Reader has errors:"
        print logger.convertToString()

    return resources

  # (else)
  return None

#----------------------------------------------------------------------
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

#----------------------------------------------------------------------
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) < 2:
    print
    print 'Standalone writer test'
    print 'Usage: python testwriter.py test_number (1-2)'
    print
    sys.exit(-1)

  try:
    test_number = int(sys.argv[1])
  except ValueError:
    print
    print 'ERROR: Invalid input for test_number; must be integer'
    sys.exit(-2)

  # Model files are hard-coded
  if test_number == 1:
    input_model = 'disk_out_ref.smtk'
  elif test_number == 2:
    input_model = 'sx_bar_hex.smtk'
  else:
    print
    print 'ERROR Invalid test number:', test_number
    print
    sys.exit(-2)

  project_name = 'test%s' % test_number
  input_crf_file = '%s.crf' % project_name

  # Load model
  this_dir = os.path.dirname(os.path.abspath(__file__))
  model_path = os.path.join(this_dir, input_model)
  model_manager = smtk.model.Manager.create()
  model = load_smtk_model(model_manager, SESSION_TYPE, model_path)
  if not model.isValid():
    print 'ERROR loading model file', model_path
    sys.exit(-1)

  # Load resource file
  resource_set = load_resources(model_manager, input_crf_file)

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

  #print 'sim_atts', sim_atts
  #print 'export_atts', export_atts
  sim_atts.setRefModelManager(model_manager)

  # 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)

  name_item = export_spec_att.findString('ProjectName')
  name_item.setValue(0, project_name)

  path_item = export_spec_att.findDirectory('ProjectDir')
  path_item.setValue(0, this_dir)

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

  print 'finis, completed:', completed
