#!/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.

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)

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)
    out_file.close()
