#!/usr/bin/python3
# Copyright 2015 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_load_functions_table.py:
#  Code generation for the load function tables used for texture formats. These mappings are
#  not renderer specific. The mappings are done from the GL internal format, to the ANGLE
#  format ID, and then for the specific data type.
#  NOTE: don't run this script directly. Run scripts/run_code_generation.py.
#

import json, sys

sys.path.append('../..')
import angle_format

template = """// GENERATED FILE - DO NOT EDIT.
// Generated by gen_load_functions_table.py using data from load_functions_data.json
//
// Copyright 2020 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.
//
// load_functions_table:
//   Contains the GetLoadFunctionsMap for texture_format_util.h
//

#include "libANGLE/renderer/load_functions_table.h"

#include "image_util/copyimage.h"
#include "image_util/generatemip.h"
#include "image_util/loadimage.h"

using namespace rx;

namespace angle
{{

namespace
{{

// ES3 image loading functions vary based on:
//    - the GL internal format (supplied to glTex*Image*D)
//    - the GL data type given (supplied to glTex*Image*D)
//    - the target DXGI_FORMAT that the image will be loaded into (which is chosen based on the D3D
//    device's capabilities)
// This map type determines which loading function to use, based on these three parameters.
// Source formats and types are taken from Tables 3.2 and 3.3 of the ES 3 spec.
void UnimplementedLoadFunction(size_t width,
                               size_t height,
                               size_t depth,
                               const uint8_t *input,
                               size_t inputRowPitch,
                               size_t inputDepthPitch,
                               uint8_t *output,
                               size_t outputRowPitch,
                               size_t outputDepthPitch)
{{
    UNIMPLEMENTED();
}}

void UnreachableLoadFunction(size_t width,
                             size_t height,
                             size_t depth,
                             const uint8_t *input,
                             size_t inputRowPitch,
                             size_t inputDepthPitch,
                             uint8_t *output,
                             size_t outputRowPitch,
                             size_t outputDepthPitch)
{{
    UNREACHABLE();
}}

{load_functions_data}}}  // namespace

LoadFunctionMap GetLoadFunctionsMap(GLenum {internal_format}, FormatID {angle_format})
{{
    // clang-format off
    switch ({internal_format})
    {{
{switch_data}
        default:
            break;
    }}
    // clang-format on
    ASSERT(internalFormat == GL_NONE || angleFormat == angle::FormatID::NONE);
    static LoadFunctionMap emptyLoadFunctionsMap;
    return emptyLoadFunctionsMap;

}}  // GetLoadFunctionsMap

}}  // namespace angle
"""

internal_format_param = 'internalFormat'
angle_format_param = 'angleFormat'
angle_format_unknown = 'NONE'


def load_functions_name(internal_format, angle_format):
    return internal_format[3:] + "_to_" + angle_format


def unknown_func_name(internal_format):
    return load_functions_name(internal_format, "default")


def get_load_func(func_name, type_functions):
    snippet = "LoadImageFunctionInfo " + func_name + "(GLenum type)\n"
    snippet += "{\n"
    snippet += "    switch (type)\n"
    snippet += "    {\n"
    for gl_type, load_function in sorted(type_functions.items()):
        snippet += "        case " + gl_type + ":\n"
        requiresConversion = str('LoadToNative<' not in load_function).lower()
        snippet += "            return LoadImageFunctionInfo(" + load_function + ", " + requiresConversion + ");\n"
    snippet += "        default:\n"
    snippet += "            UNREACHABLE();\n"
    snippet += "            return LoadImageFunctionInfo(UnreachableLoadFunction, true);\n"
    snippet += "    }\n"
    snippet += "}\n"
    snippet += "\n"

    return snippet


def get_unknown_load_func(angle_to_type_map, internal_format):
    assert angle_format_unknown in angle_to_type_map
    return get_load_func(
        unknown_func_name(internal_format), angle_to_type_map[angle_format_unknown])


def parse_json(json_data):
    table_data = ''
    load_functions_data = ''
    for internal_format, angle_to_type_map in sorted(json_data.items()):

        s = '        '

        table_data += s + 'case ' + internal_format + ':\n'

        do_switch = len(angle_to_type_map) > 1 or list(
            angle_to_type_map)[0] != angle_format_unknown

        if do_switch:
            table_data += s + '{\n'
            s += '    '
            table_data += s + 'switch (' + angle_format_param + ')\n'
            table_data += s + '{\n'
            s += '    '

        for angle_format, type_functions in sorted(angle_to_type_map.items()):

            if angle_format == angle_format_unknown:
                continue

            func_name = load_functions_name(internal_format, angle_format)

            # Main case statements
            table_data += s + 'case FormatID::' + angle_format + ':\n'
            table_data += s + '    return ' + func_name + ';\n'

            if angle_format_unknown in angle_to_type_map:
                for gl_type, load_function in sorted(
                        angle_to_type_map[angle_format_unknown].items()):
                    if gl_type not in type_functions:
                        type_functions[gl_type] = load_function

            load_functions_data += get_load_func(func_name, type_functions)

        if do_switch:
            table_data += s + 'default:\n'

        has_break_in_switch = False
        if angle_format_unknown in angle_to_type_map:
            table_data += s + '    return ' + unknown_func_name(internal_format) + ';\n'
            load_functions_data += get_unknown_load_func(angle_to_type_map, internal_format)
        else:
            has_break_in_switch = True
            table_data += s + '    break;\n'

        if do_switch:
            s = s[4:]
            table_data += s + '}\n'
            if has_break_in_switch:
                # If the inner switch contains a break statement, add a break
                # statement after the switch as well.
                table_data += s + 'break;\n'
            s = s[4:]
            table_data += s + '}\n'

    return table_data, load_functions_data


def main():

    # auto_script parameters.
    if len(sys.argv) > 1:
        inputs = ['angle_format.py', 'load_functions_data.json']
        outputs = ['load_functions_table_autogen.cpp']

        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

    json_data = angle_format.load_json('load_functions_data.json')

    switch_data, load_functions_data = parse_json(json_data)
    output = template.format(
        internal_format=internal_format_param,
        angle_format=angle_format_param,
        switch_data=switch_data,
        load_functions_data=load_functions_data)

    with open('load_functions_table_autogen.cpp', 'wt') as out_file:
        out_file.write(output)
        out_file.close()
    return 0


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