#! /usr/bin/env python
#
# runsvm.py
# 
#    Runs the Sedona VM in current directory with supplied options (or defaults).
#
# Author:    Elizabeth McKenney
# Creation:  27 Oct 2011
#                 

import sys
import os
import subprocess
#import optparse 
import argparse 
import shutil 

import env


#
# initParser
#   Initializes the options parser
#
def initParser():
  global parser

  parser = argparse.ArgumentParser(description='Run Sedona VM on Windows')

  parser.add_argument("-a", "--app", default="app.sab", action="store",
                    help="Use AFILE for app file (default is ./app.sab)", 
                    metavar="AFILE")
 
  parser.add_argument("-b", "--bin", default="svm.exe", action="store",
                    help="Run BINFILE as SVM (default is svm.exe)", 
                    metavar="BINFILE")

  parser.add_argument("-s", "--scode", default="kits.scode", action="store",
                    help="Use SFILE for scode file (default is ./kits.scode)", 
                    metavar="SFILE")

  parser.add_argument("-u", "--useplat", default=None, action="store",
                    help="Run specific SVM for PLATFORM_ID", 
                    metavar="PLATFORM_ID")
  
  modegroup = parser.add_mutually_exclusive_group()

  modegroup.add_argument("-p", "--plat", action="store_true", default=False,
                    help="Run the SVM in platform mode")

  modegroup.add_argument("-t", "--test", action="store_true", default=False,
                    help="Run the SVM in test mode")


#
# usage
#  Print usage (e.g. on error condition)
#
def usage():
  global parser

  # Just print the help generated by the parser for --help
  print ""
  parser.print_help()


#
# findlatest
#   Returns newest subdir in given dir
#
def findlatest(basedir):
  latest  = None
  lastmod = None
  for d in os.listdir(basedir):
    fd = os.path.join(basedir, d)
    if not os.path.isdir(fd): continue
    stats = os.stat( fd )
    if not lastmod or stats.st_mtime > lastmod:
      latest = d
      lastmod = stats.st_mtime
  return latest



#
# Main
#
def main():
  global parser, options

  options = parser.parse_args()

  # If specific platform is specified, assume app & scode are in same folder with svm
  if options.useplat:

    # Assemble path to svm folder based on platform ID
    svmDir = os.path.join(env.platforms, "db")
    for d in options.useplat.split("-"):
      svmDir = os.path.join(svmDir, d)
    if not os.path.isdir( os.path.join(svmDir, ".par") ):
      lastchk = findlatest(svmDir)
      if lastchk: svmDir = os.path.join(svmDir, lastchk)
    svmDir = os.path.join(svmDir, ".par", "svm")

    print "svmDir = " + svmDir

    # If anything missing, bail
    if not os.path.isdir(svmDir):
      raise Exception, "\n ERROR: Platform archive does not contain necessary files to run."


    # Get filenames for svm, app, scode in plat archive
    appFile = None
    scodeFile = None
    svmFile = None
    for sf in os.listdir(svmDir):
      (p, e) = os.path.splitext(sf)
      if e=='.scode' and not scodeFile: scodeFile = sf
      elif e=='.sab' and not appFile: appFile = sf
      elif not svmFile: svmFile = sf

    # If anything missing, bail
    if not appFile or not scodeFile or not svmFile:
      raise Exception, "\n ERROR: To run from platform archive, must have all files present.\n"

    # Use the three files to run the SVM  (overrides any cmd line settings!)
    options.app = os.path.join(svmDir, appFile)
    options.scode = os.path.join(svmDir, scodeFile)
    options.bin = os.path.join(svmDir, svmFile)


  cmd = options.bin

  if options.plat==True:
    if not options.scode=="kits.scode":
      shutil.copy(options.scode, "kits.scode")
    if not options.app=="app.sab":
      shutil.copy(options.app, "app.sab")
    cmd += " --plat"

  else:
    cmd += " " + options.scode
    cmd += " " + options.app

  # svm.exe switches must go at end of command line 
  if options.test==True:
    cmd += " -test"

  # During development, print the full command line before executing
  #print "\n\n   Executing cmd = { " + cmd + " }\n\n"
  
  if subprocess.call(cmd, shell=True):
    raise Exception, "\n *** Failed:\n" + cmd


# 
# Main 
#
if __name__ == '__main__':

  # Initialize the options parser
  initParser()

  # Call the main function
  main()

