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