#!/usr/bin/env python3
# Copyright (c) 2013, 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.
#
# This python script creates a source path mapping in a C++ source file from
# a C++ source template and list of dart library files.

import os
import sys
import utils

from os.path import join
from optparse import OptionParser

HOST_OS = utils.GuessOS()


def makeString(input_file, var_name):
    result = 'static const char ' + var_name + '[] = {\n '
    fileHandle = open(input_file, 'rb')
    lineCounter = 0
    for byte in fileHandle.read():
        result += '\'\\x%02x' % ord(byte) + '\', '
        lineCounter += 1
        if lineCounter == 19:
            result += '\n '
            lineCounter = 0
    result += '0};\n'
    return result


def makeSourceArrays(in_files):
    result = ''
    file_count = 0
    for string_file in in_files:
        if string_file.endswith('.dart'):
            file_count += 1
            file_string = makeString(string_file,
                                     "source_array_" + str(file_count))
            result += file_string
    return result


def makeFile(output_file, input_cc_file, include, var_name, lib_name, in_files):
    part_index = []
    bootstrap_cc_text = open(input_cc_file).read()
    bootstrap_cc_text = bootstrap_cc_text.replace("{{SOURCE_ARRAYS}}",
                                                  makeSourceArrays(in_files))
    bootstrap_cc_text = bootstrap_cc_text.replace("{{INCLUDE}}", include)
    bootstrap_cc_text = bootstrap_cc_text.replace("{{VAR_NAME}}", var_name)
    main_file_found = False
    file_count = 0
    for string_file in in_files:
        if string_file.endswith('.dart'):
            file_count += 1
            if (not main_file_found):
                inpt = open(string_file, 'r')
                for line in inpt:
                    # File with library tag is the main file.
                    if line.startswith('library '):
                        main_file_found = True
                        bootstrap_cc_text = bootstrap_cc_text.replace(
                            "{{LIBRARY_SOURCE_MAP}}", ' "' + lib_name + '",\n' +
                            ' source_array_' + str(file_count) + ',\n')
                inpt.close()
                if (main_file_found):
                    continue
            part_index.append(' "' + lib_name + "/" + os.path.basename(
                string_file).replace('\\', '\\\\') + '",\n')
            part_index.append(' source_array_' + str(file_count) + ',\n\n')
    bootstrap_cc_text = bootstrap_cc_text.replace("{{LIBRARY_SOURCE_MAP}}", '')
    bootstrap_cc_text = bootstrap_cc_text.replace("{{PART_SOURCE_MAP}}",
                                                  ''.join(part_index))
    open(output_file, 'w').write(bootstrap_cc_text)
    return True


def main(args):
    try:
        # Parse input.
        parser = OptionParser()
        parser.add_option(
            "--output", action="store", type="string", help="output file name")
        parser.add_option(
            "--input_cc",
            action="store",
            type="string",
            help="input template file")
        parser.add_option(
            "--include", action="store", type="string", help="variable name")
        parser.add_option(
            "--library_name",
            action="store",
            type="string",
            help="library name")
        parser.add_option(
            "--var_name", action="store", type="string", help="variable name")

        (options, args) = parser.parse_args()
        if not options.output:
            sys.stderr.write('--output not specified\n')
            return -1
        if not len(options.input_cc):
            sys.stderr.write('--input_cc not specified\n')
            return -1
        if not len(options.include):
            sys.stderr.write('--include not specified\n')
            return -1
        if not len(options.var_name):
            sys.stderr.write('--var_name not specified\n')
            return -1
        if not len(options.library_name):
            sys.stderr.write('--library_name not specified\n')
            return -1
        if len(args) == 0:
            sys.stderr.write('No input files specified\n')
            return -1

        files = []
        for arg in args:
            files.append(arg)

        if not makeFile(options.output, options.input_cc, options.include,
                        options.var_name, options.library_name, files):
            return -1

        return 0
    except Exception as inst:
        sys.stderr.write('gen_library_src_paths.py exception\n')
        sys.stderr.write(str(inst))
        sys.stderr.write('\n')
        return -1


if __name__ == '__main__':
    sys.exit(main(sys.argv))
