#!/usr/bin/python
# 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_format_map.py:
#  Code generation for GL format map. The format map matches between
#  {format,type} and internal format.
#  NOTE: don't run this script directly. Run scripts/run_code_generation.py.

from datetime import date
import sys

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

template_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {data_source_name}.
// ES3 format info from {es3_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.
//
// 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
{{

GLenum GetSizedFormatInternal(GLenum format, GLenum type)
{{
    switch (format)
    {{
{format_cases}        case GL_NONE:
            return GL_NONE;

        default:
            break;
    }}

    return GL_NONE;
}}

bool ValidES3Format(GLenum format)
{{
    switch (format)
    {{
{es3_format_cases}            return true;

        default:
            return false;
    }}
}}

bool ValidES3Type(GLenum type)
{{
    switch (type)
    {{
{es3_type_cases}            return true;

        default:
            return false;
    }}
}}

bool ValidES3FormatCombination(GLenum format, GLenum type, GLenum internalFormat)
{{
    ASSERT(ValidES3Format(format) && ValidES3Type(type));

    switch (format)
    {{
{es3_combo_cases}        default:
            UNREACHABLE();
            break;
    }}

    return false;
}}

}}  // namespace gl
"""

template_format_case = """        case {format}:
            switch (type)
            {{
{type_cases}                default:
                    break;
            }}
            break;

"""

template_simple_case = """                case {key}:
                    return {result};
"""

template_es3_combo_type_case = """                case {type}:
                {{
                    switch (internalFormat)
                    {{
{internal_format_cases}                            return true;
                        default:
                            break;
                    }}
                    break;
                }}
"""


def parse_type_case(type, result):
    return template_simple_case.format(key=type, result=result)


def parse_format_case(format, type_map):
    type_cases = ""
    for type, internal_format in sorted(type_map.iteritems()):
        type_cases += parse_type_case(type, internal_format)
    return template_format_case.format(format=format, type_cases=type_cases)


def main():

    # auto_script parameters.
    if len(sys.argv) > 1:
        inputs = ['es3_format_type_combinations.json', 'format_map_data.json']
        outputs = ['format_map_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

    input_script = 'format_map_data.json'

    format_map = angle_format.load_json(input_script)

    format_cases = ""

    for format, type_map in sorted(format_map.iteritems()):
        format_cases += parse_format_case(format, type_map)

    combo_data_file = 'es3_format_type_combinations.json'
    es3_combo_data = angle_format.load_json(combo_data_file)
    combo_data = [combo for sublist in es3_combo_data.values() for combo in sublist]

    types = set()
    formats = set()
    combos = {}

    for internal_format, format, type in combo_data:
        types.update([type])
        formats.update([format])
        if format not in combos:
            combos[format] = {}
        if type not in combos[format]:
            combos[format][type] = [internal_format]
        else:
            combos[format][type] += [internal_format]

    es3_format_cases = ""

    for format in sorted(formats):
        es3_format_cases += "        case " + format + ":\n"

    es3_type_cases = ""

    for type in sorted(types):
        es3_type_cases += "        case " + type + ":\n"

    es3_combo_cases = ""

    for format, type_combos in combos.iteritems():
        this_type_cases = ""
        for type, combos in type_combos.iteritems():
            internal_format_cases = ""
            for internal_format in combos:
                internal_format_cases += "                        case " + internal_format + ":\n"

            this_type_cases += template_es3_combo_type_case.format(
                type=type, internal_format_cases=internal_format_cases)

        es3_combo_cases += template_format_case.format(format=format, type_cases=this_type_cases)

    with open('format_map_autogen.cpp', 'wt') as out_file:
        output_cpp = template_cpp.format(
            script_name=sys.argv[0],
            data_source_name=input_script,
            es3_data_source_name=combo_data_file,
            copyright_year=date.today().year,
            format_cases=format_cases,
            es3_format_cases=es3_format_cases,
            es3_type_cases=es3_type_cases,
            es3_combo_cases=es3_combo_cases)
        out_file.write(output_cpp)
    return 0


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