#!/usr/bin/python
# Copyright 2017 The ANGLE Project Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# gen_emulated_builtin_function_tables.py:
#  Generator for the builtin function maps.
#  NOTE: don't run this script directly. Run scripts/run_code_generation.py.

from datetime import date
import json
import os, sys

template_emulated_builtin_functions_hlsl = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name}.
//
// Copyright {copyright_year} The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// emulated_builtin_functions_hlsl:
//   HLSL code for emulating GLSL builtin functions not present in HLSL.

#include "compiler/translator/BuiltInFunctionEmulator.h"
#include "compiler/translator/tree_util/BuiltIn.h"

namespace sh
{{

namespace
{{

struct FunctionPair
{{
   constexpr FunctionPair(const TSymbolUniqueId &idIn, const char *bodyIn) : id(idIn.get()), body(bodyIn)
   {{
   }}

   int id;
   const char *body;
}};

const FunctionPair g_hlslFunctions[] = {{
{emulated_functions}}};
}}  // anonymous namespace

const char *FindHLSLFunction(int uniqueId)
{{
    for (size_t index = 0; index < ArraySize(g_hlslFunctions); ++index)
    {{
        const auto &function = g_hlslFunctions[index];
        if (function.id == uniqueId)
        {{
            return function.body;
        }}
    }}

    return nullptr;
}}
}}  // namespace sh
"""


def reject_duplicate_keys(pairs):
    found_keys = {}
    for key, value in pairs:
        if key in found_keys:
            raise ValueError("duplicate key: %r" % (key,))
        else:
            found_keys[key] = value
    return found_keys


def load_json(path):
    with open(path) as map_file:
        file_data = map_file.read()
        map_file.close()
        return json.loads(file_data, object_pairs_hook=reject_duplicate_keys)


def enum_type(arg):
    # handle 'argtype argname' and 'out argtype argname'
    chunks = arg.split(' ')
    arg_type = chunks[0]
    if len(chunks) == 3:
        arg_type = chunks[1]

    suffix = ""
    if not arg_type[-1].isdigit():
        suffix = '1'
    if arg_type[0:4] == 'uint':
        return 'UI' + arg_type[2:] + suffix
    return arg_type.capitalize() + suffix


def gen_emulated_function(data):

    func = ""
    if 'comment' in data:
        func += "".join(["// " + line + "\n" for line in data['comment']])

    sig = data['return_type'] + ' ' + data['op'] + '_emu(' + ', '.join(data['args']) + ')'
    body = [sig, '{'] + ['    ' + line for line in data['body']] + ['}']

    func += "{\n"
    func += "BuiltInId::" + data['op'] + "_" + "_".join([enum_type(arg) for arg in data['args']
                                                        ]) + ",\n"
    if 'helper' in data:
        func += '"' + '\\n"\n"'.join(data['helper']) + '\\n"\n'
    func += '"' + '\\n"\n"'.join(body) + '\\n"\n'
    func += "},\n"
    return [func]


def main():

    input_script = "emulated_builtin_function_data_hlsl.json"
    hlsl_fname = "emulated_builtin_functions_hlsl_autogen.cpp"

    # auto_script parameters.
    if len(sys.argv) > 1:
        inputs = [input_script]
        outputs = [hlsl_fname]

        if sys.argv[1] == 'inputs':
            print ','.join(inputs)
        elif sys.argv[1] == 'outputs':
            print ','.join(outputs)
        else:
            print('Invalid script parameters')
            return 1
        return 0

    hlsl_json = load_json(input_script)
    emulated_functions = []

    for item in hlsl_json:
        emulated_functions += gen_emulated_function(item)

    hlsl_gen = template_emulated_builtin_functions_hlsl.format(
        script_name=sys.argv[0],
        data_source_name=input_script,
        copyright_year=date.today().year,
        emulated_functions="".join(emulated_functions))

    with open(hlsl_fname, 'wt') as f:
        f.write(hlsl_gen)
        f.close()

    return 0


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