#!/usr/bin/python3
#
# Copyright 2022 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_interpreter_utils.py:
#   Code generator for the GLC interpreter.
#   NOTE: don't run this script directly. Run scripts/run_code_generation.py.

import os
import re
import sys

import registry_xml

EXIT_SUCCESS = 0
EXIT_FAILURE = 1

BASE_PATH = '../util/capture/trace_interpreter_autogen'

CPP_TEMPLATE = """\
// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name}.
//
// Copyright 2022 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.
//
// {file_name}.cpp:
//   Helper code for trace interpreter.

#include "angle_trace_gl.h"
#include "trace_fixture.h"
#include "trace_interpreter.h"

namespace angle
{{
CallCapture ParseCallCapture(const Token &nameToken, size_t numParamTokens, const Token *paramTokens, const TraceStringMap &strings)
{{
{parse_cases}
    if (numParamTokens > 0)
    {{
        printf("Expected zero parameter tokens for %s\\n", nameToken);
        UNREACHABLE();
    }}
    return CallCapture(nameToken, ParamBuffer());
}}

{dispatch_cases}

void ReplayCustomFunctionCall(const CallCapture &call, const TraceFunctionMap &customFunctions)
{{
    ASSERT(call.entryPoint == EntryPoint::Invalid);
    const Captures &captures = call.params.getParamCaptures();

{custom_dispatch_cases}

    auto iter = customFunctions.find(call.customFunctionName);
    if (iter == customFunctions.end())
    {{
        printf("Unknown custom function: %s\\n", call.customFunctionName.c_str());
        UNREACHABLE();
    }}
    else
    {{
        ASSERT(call.params.empty());
        const TraceFunction &customFunc = iter->second;
        for (const CallCapture &customCall : customFunc)
        {{
            ReplayTraceFunctionCall(customCall, customFunctions);
        }}
    }}
}}
}}  // namespace angle
"""

PARSE_CASE = """\
    if (strcmp(nameToken, "{ep}") == 0)
    {{
        ParamBuffer params = ParseParameters<{pfn}>(paramTokens, strings);
        return CallCapture({call}, std::move(params));
    }}
"""

CUSTOM_DISPATCH_CASE = """\
    if (call.customFunctionName == "{fn}")
    {{
        DispatchCallCapture({fn}, captures);
        return;
    }}
"""

DISPATCH_CASE = """\
template <typename Fn, EnableIfNArgs<Fn, {nargs}> = 0>
void DispatchCallCapture(Fn *fn, const Captures &cap)
{{
    (*fn)({args});
}}
"""

FIXTURE_H = '../util/capture/trace_fixture.h'


def GetFunctionsFromFixture():
    funcs = []
    arg_counts = set()
    pattern = 'void '
    with open(FIXTURE_H) as f:
        lines = f.read().split(';')
        for line in lines:
            line = re.sub('// .*\n', '', line.strip())
            if line.startswith(pattern):
                func_name = line[len(pattern):line.find('(')]
                func_args = line.count(',') + 1
                funcs.append(func_name)
                arg_counts.add(func_args)
        f.close()
    return sorted(list(set(funcs))), arg_counts


def get_dispatch(n):
    return ', '.join(['Arg<Fn, %d>(cap)' % i for i in range(n)])


def main(cpp_output_path):
    gles = registry_xml.GetGLES()
    egl = registry_xml.GetEGL()

    def fn(ep):
        return 'std::remove_pointer<PFN%sPROC>::type' % ep.upper()

    fixture_functions, arg_counts = GetFunctionsFromFixture()

    eps_and_enums = sorted(list(set(gles.GetEnums() + egl.GetEnums())))
    parse_cases = [
        PARSE_CASE.format(ep=ep, pfn=fn(ep), call='EntryPoint::%s' % enum)
        for (enum, ep) in eps_and_enums
    ]
    parse_cases += [
        PARSE_CASE.format(ep=fn, pfn='decltype(%s)' % fn, call='"%s"' % fn)
        for fn in fixture_functions
    ]

    dispatch_cases = [DISPATCH_CASE.format(nargs=n, args=get_dispatch(n)) for n in arg_counts]

    custom_dispatch_cases = [CUSTOM_DISPATCH_CASE.format(fn=fn) for fn in fixture_functions]

    format_args = {
        'script_name': os.path.basename(sys.argv[0]),
        'data_source_name': 'gl.xml and gl_angle_ext.xml',
        'file_name': os.path.basename(BASE_PATH),
        'parse_cases': ''.join(parse_cases),
        'dispatch_cases': '\n'.join(dispatch_cases),
        'custom_dispatch_cases': ''.join(custom_dispatch_cases),
    }

    cpp_content = CPP_TEMPLATE.format(**format_args)
    cpp_output_path = registry_xml.script_relative(cpp_output_path)
    with open(cpp_output_path, 'w') as f:
        f.write(cpp_content)

    return EXIT_SUCCESS


if __name__ == '__main__':
    inputs = registry_xml.xml_inputs + [FIXTURE_H]
    outputs = [
        '%s.cpp' % BASE_PATH,
    ]

    if len(sys.argv) > 1:
        if sys.argv[1] == 'inputs':
            print(','.join(inputs))
        elif sys.argv[1] == 'outputs':
            print(','.join(outputs))
    else:
        sys.exit(main(registry_xml.script_relative(outputs[0])))
