#!/usr/bin/python3
# Copyright 2016 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_copy_conversion_table.py:
#  Code generation for ES3 valid copy conversions table format map.
#  NOTE: don't run this script directly. Run scripts/run_code_generation.py.

import sys
import os

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

template_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name}.
//
// Copyright 2016 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.
//
// format_map:
//   Determining the sized internal format from a (format,type) pair.
//   Also check es3 format combinations for validity.

#include "angle_gl.h"
#include "common/debug.h"

namespace gl
{{

bool ValidES3CopyConversion(GLenum textureFormat, GLenum framebufferFormat)
{{
    switch (textureFormat)
    {{
{texture_format_cases}        default:
            break;
    }}

    return false;
}}

}}  // namespace gl
"""

template_format_case = """        case {texture_format}:
            switch (framebufferFormat)
            {{
{framebuffer_format_cases}                    return true;
                default:
                    break;
            }}
            break;

"""

template_simple_case = """                case {key}:
"""


def parse_texture_format_case(texture_format, framebuffer_formats):
    framebuffer_format_cases = ""
    for framebuffer_format in sorted(framebuffer_formats):
        framebuffer_format_cases += template_simple_case.format(key=framebuffer_format)
    return template_format_case.format(
        texture_format=texture_format, framebuffer_format_cases=framebuffer_format_cases)


def main():

    data_source_name = 'es3_copy_conversion_formats.json'
    out_file_name = 'es3_copy_conversion_table_autogen.cpp'

    # auto_script parameters.
    if len(sys.argv) > 1:
        inputs = ['renderer/angle_format.py', data_source_name]
        outputs = [out_file_name]

        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(data_source_name)

    format_map = {}

    for description, data in sorted(json_data.items()):
        for texture_format, framebuffer_format in data:
            if texture_format not in format_map:
                format_map[texture_format] = []
            format_map[texture_format] += [framebuffer_format]

    texture_format_cases = ""

    for texture_format, framebuffer_formats in sorted(format_map.items()):
        texture_format_cases += parse_texture_format_case(texture_format, framebuffer_formats)

    with open(out_file_name, 'wt') as out_file:
        output_cpp = template_cpp.format(
            script_name=os.path.basename(sys.argv[0]),
            data_source_name=data_source_name,
            texture_format_cases=texture_format_cases)
        out_file.write(output_cpp)
        out_file.close()
    return 0


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