#!/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(
        "--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 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())
