#!/usr/bin/env python
#
# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

"""Script to create snapshot bin file."""

import getopt
import optparse
import os
from os.path import basename, join
import sys
import utils


def BuildOptions():
  result = optparse.OptionParser()
  result.add_option("--executable",
      action="store", type="string",
      help="path to snapshot generator executable")
  result.add_option("--snapshot_kind",
      action="store", type="string",
      help="kind of snapshot to generate",
      default="core")
  result.add_option("--load_compilation_trace",
      action="store", type="string",
      help="path to a compilation trace to load before generating a core-jit snapshot")
  result.add_option("--vm_flag",
      action="append", type="string", default=[],
      help="pass additional Dart VM flag")
  result.add_option("--vm_output_bin",
      action="store", type="string",
      help="output file name into which vm isolate snapshot in binary form " +
           "is generated")
  result.add_option("--vm_instructions_output_bin",
      action="store", type="string",
      help="output file name into which vm isolate snapshot in binary form " +
           "is generated")
  result.add_option("--isolate_output_bin",
      action="store", type="string",
      help="output file name into which isolate snapshot in binary form " +
           "is generated")
  result.add_option("--isolate_instructions_output_bin",
      action="store", type="string",
      help="output file name into which isolate snapshot in binary form " +
           "is generated")
  result.add_option("--script",
      action="store", type="string",
      help="Dart script for which snapshot is to be generated")
  result.add_option("--package_root",
      action="store", type="string",
      help="path used to resolve package: imports.")
  result.add_option("--packages",
      action="store", type="string",
      help="package config file used to reasolve package: imports.")
  result.add_option("-v", "--verbose",
      help='Verbose output.',
      default=False, action="store_true")
  result.add_option("--timestamp_file",
      action="store", type="string",
      help="Path to timestamp file that will be written",
      default="")
  return result


def ProcessOptions(options):
  if not options.executable:
    sys.stderr.write('--executable not specified\n')
    return False
  if not options.snapshot_kind:
    sys.stderr.write('--snapshot_kind not specified\n')
    return False
  if not options.vm_output_bin:
    sys.stderr.write('--vm_output_bin not specified\n')
    return False
  if not options.isolate_output_bin:
    sys.stderr.write('--isolate_output_bin not specified\n')
    return False
  if (options.snapshot_kind == 'core-jit'
      and not options.vm_instructions_output_bin):
    sys.stderr.write('--vm_instructions_output_bin not specified\n')
    return False
  if (options.snapshot_kind == 'core-jit'
      and not options.isolate_instructions_output_bin):
    sys.stderr.write('--isolate_instructions_output_bin not specified\n')
    return False
  return True


def CreateTimestampFile(options):
  if options.timestamp_file != '':
    dir_name = os.path.dirname(options.timestamp_file)
    if not os.path.exists(dir_name):
      os.mkdir(dir_name)
    open(options.timestamp_file, 'w').close()


def Main():
  # Parse options.
  parser = BuildOptions()
  (options, args) = parser.parse_args()
  if not ProcessOptions(options):
    parser.print_help()
    return 1

  # If there are additional arguments, report error and exit.
  if args:
    parser.print_help()
    return 1

  # Setup arguments to the snapshot generator binary.
  script_args = ["--ignore_unrecognized_flags"]

  for flag in options.vm_flag:
    script_args.append(flag)

  if options.load_compilation_trace:
    script_args.append(''.join([ "--load_compilation_trace=", options.load_compilation_trace]))

  # Pass along the package_root if there is one.
  if options.package_root:
    script_args.append(''.join([ "--package_root=", options.package_root]))

  # Pass along the packages if there is one.
  if options.packages:
    script_args.append(''.join([ "--packages=", options.packages]))

  # First setup the vm isolate and regular isolate snapshot output filename.
  script_args.append(''.join([ "--snapshot_kind=", options.snapshot_kind ]))
  script_args.append(''.join([ "--vm_snapshot_data=", options.vm_output_bin ]))
  script_args.append(''.join([ "--isolate_snapshot_data=", options.isolate_output_bin ]))

  if options.vm_instructions_output_bin != None:
    script_args.append(''.join([ "--vm_snapshot_instructions=",
                                 options.vm_instructions_output_bin ]))
  if options.isolate_instructions_output_bin != None:
    script_args.append(''.join([ "--isolate_snapshot_instructions=",
                                 options.isolate_instructions_output_bin ]))

  # Finally append the script name if one is specified.
  if options.script:
    script_args.append(options.script)

  # Construct command line to execute the snapshot generator binary and invoke.
  command = [ options.executable ] + script_args
  try:
    utils.RunCommand(command, outStream=sys.stderr, errStream=sys.stderr,
                     verbose=options.verbose, printErrorInfo=True)
  except Exception as e:
    return -1

  # Success, update timestamp file.
  CreateTimestampFile(options)

  return 0


if __name__ == '__main__':
  sys.exit(Main())
