#!/usr/bin/env python3
#
# 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(
        "--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
    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)

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