#!/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_vk_format_table.py:
#  Code generation for vk format map

from datetime import date
import json
import math
import pprint
import os
import re
import sys

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

template_table_autogen_cpp = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {input_file_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.
//
// {out_file_name}:
//   Queries for full Vulkan format information based on GL format.

#include "libANGLE/renderer/vulkan/formatutilsvk.h"

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

using namespace angle;

namespace rx
{{

namespace vk
{{

// static
const Format &Format::Get(GLenum internalFormat)
{{
    // clang-format off
    switch (internalFormat)
    {{
{format_case_data}
        default:
            break;
    }}
    // clang-format on

    UNREACHABLE();
    static const Format noInfo(GL_NONE, angle::Format::ID::NONE, VK_FORMAT_UNDEFINED, nullptr);
    return noInfo;
}}

}}  // namespace vk

}}  // namespace rx
"""

format_entry_template = """{space}{{
{space}    static constexpr Format info({internalFormat},
{space}                                 angle::Format::ID::{formatName},
{space}                                 {vkFormat},
{space}                                 {initializer});
{space}    return info;
{space}}}
"""

def parse_format_case(internal_format, format_name, native_format):

    table_data = ""

    parsed = {
        "space": "        ",
        "internalFormat": internal_format,
        "formatName": format_name,
        "vkFormat": native_format,
    }

    # Derived values.
    parsed["initializer"] = angle_format.get_internal_format_initializer(
        internal_format, format_name)

    return format_entry_template.format(**parsed)

def parse_json_into_cases(json_map, vk_map):
    table_data = ''

    for internal_format, format_name in sorted(json_map.iteritems()):

        if format_name not in vk_map:
            continue

        native_format = vk_map[format_name]

        table_data += '        case ' + internal_format + ':\n'
        table_data += parse_format_case(internal_format, format_name, native_format)

    return table_data

input_file_name = 'vk_format_map.json'
out_file_name = 'vk_format_table'

json_map = angle_format.load_without_override()
vk_map = angle_format.load_json(input_file_name)

format_case_data = parse_json_into_cases(json_map, vk_map)
output_cpp = template_table_autogen_cpp.format(
    copyright_year = date.today().year,
    format_case_data = format_case_data,
    script_name = __file__,
    out_file_name = out_file_name,
    input_file_name = input_file_name)

with open(out_file_name + '_autogen.cpp', 'wt') as out_file:
    out_file.write(output_cpp)
    out_file.close()
