#!/usr/bin/env python3
#
# Copyright (c) 2011, 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 convert snapshot files to a C++ file which can be compiled and
# linked together with VM binary.

import getopt
import optparse
import string
import subprocess
import sys
import utils

HOST_OS = utils.GuessOS()
HOST_CPUS = utils.GuessCpus()


def BuildOptions():
    result = optparse.OptionParser()
    result.add_option(
        "--vm_input_bin",
        action="store",
        type="string",
        help="input file name of the vm isolate snapshot in binary form")
    result.add_option(
        "--input_bin",
        action="store",
        type="string",
        help="input file name of the isolate snapshot in binary form")
    result.add_option(
        "--input_cc",
        action="store",
        type="string",
        help="input file name which contains the C buffer template")
    result.add_option(
        "--output",
        action="store",
        type="string",
        help="output file name into which snapshot in C buffer form is generated"
    )
    result.add_option(
        "-v",
        "--verbose",
        help='Verbose output.',
        default=False,
        action="store_true")
    return result


def ProcessOptions(options):
    if not options.vm_input_bin:
        sys.stderr.write('--vm_input_bin not specified\n')
        return False
    if not options.input_bin:
        sys.stderr.write('--input_bin not specified\n')
        return False
    if not options.input_cc:
        sys.stderr.write('--input_cc not specified\n')
        return False
    if not options.output:
        sys.stderr.write('--output not specified\n')
        return False
    return True


def WriteBytesAsText(out, input_file):
    """Writes byte contents of the input_file into out file as text.

  Output is formatted as a list of comma separated integer values - one value
  for each byte.
  """
    with open(input_file, 'rb') as input:
        lineCounter = 0
        line = ' '
        for byte in input.read():
            line += ' %d,' % ord(byte)
            lineCounter += 1
            if lineCounter == 10:
                out.write(line + '\n')
                line = ' '
                lineCounter = 0
        if lineCounter != 0:
            out.write(line + '\n')


def GenerateFileFromTemplate(output_file, input_cc_file, vm_isolate_input_file,
                             isolate_input_file):
    """Generates C++ file based on a input_cc_file template and two binary files

  Template is expected to have two %s placeholders which would be filled
  with binary contents of the given files each formatted as a comma separated
  list of integers.
  """
    snapshot_cc_text = open(input_cc_file).read()
    chunks = snapshot_cc_text.split("%s")
    if len(chunks) != 3:
        raise Exception("Template %s should contain exactly two %%s occurrences"
                        % input_cc_file)

    with open(output_file, 'w') as out:
        out.write(chunks[0])
        WriteBytesAsText(out, vm_isolate_input_file)
        out.write(chunks[1])
        WriteBytesAsText(out, isolate_input_file)
        out.write(chunks[2])


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

    GenerateFileFromTemplate(options.output, options.input_cc,
                             options.vm_input_bin, options.input_bin)

    return 0


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