#!/usr/bin/python
# Copyright 2019 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_mtl_format_table.py:
#  Code generation for Metal format map.
#  NOTE: don't run this script directly. Run scripts/run_code_generation.py.
#

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

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

template_autogen_inl = """// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {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.
//
// Metal Format table:
//   Conversion from ANGLE format to Metal format.

#import <Metal/Metal.h>
#include <TargetConditionals.h>

#include "libANGLE/renderer/Format.h"
#include "libANGLE/renderer/metal/DisplayMtl.h"
#include "libANGLE/renderer/metal/mtl_format_utils.h"

namespace rx
{{
namespace mtl
{{

void Format::init(const DisplayMtl *display, angle::FormatID intendedFormatId_)
{{
    this->intendedFormatId = intendedFormatId_;

    id<MTLDevice> metalDevice = display->getMetalDevice();

    // Actual conversion
    switch (this->intendedFormatId)
    {{
{angle_image_format_switch}
    }}
}}

void VertexFormat::init(angle::FormatID angleFormatId, bool tightlyPacked)
{{
    this->intendedFormatId = angleFormatId;

    // Actual conversion
    switch (this->intendedFormatId)
    {{
{angle_vertex_format_switch}
    }}
}}

}}  // namespace mtl
}}  // namespace rx
"""

case_image_format_template1 = """        case angle::FormatID::{angle_format}:
            this->metalFormat = {mtl_format};
            this->actualFormatId = angle::FormatID::{actual_angle_format};
            break;

"""

case_image_format_template2 = """        case angle::FormatID::{angle_format}:
            if (metalDevice.depth24Stencil8PixelFormatSupported)
            {{
                this->metalFormat = {mtl_format};
                this->actualFormatId = angle::FormatID::{actual_angle_format};
            }}
            else
            {{
                this->metalFormat = {mtl_format_fallback};
                this->actualFormatId = angle::FormatID::{actual_angle_format_fallback};
            }}
            break;

"""

case_vertex_format_template1 = """        case angle::FormatID::{angle_format}:
            this->metalFormat = {mtl_format};
            this->actualFormatId = angle::FormatID::{actual_angle_format};
            this->vertexLoadFunction = {vertex_copy_function};
            break;

"""

case_vertex_format_template2 = """        case angle::FormatID::{angle_format}:
            if (tightlyPacked)
            {{
                this->metalFormat = {mtl_format_packed};
                this->actualFormatId = angle::FormatID::{actual_angle_format_packed};
                this->vertexLoadFunction = {vertex_copy_function_packed};
            }}
            else
            {{
                this->metalFormat = {mtl_format};
                this->actualFormatId = angle::FormatID::{actual_angle_format};
                this->vertexLoadFunction = {vertex_copy_function};
            }}
            break;

"""


def gen_image_map_switch_simple_case(angle_format, actual_angle_format, angle_to_mtl_map):
    mtl_format = angle_to_mtl_map[actual_angle_format]
    return case_image_format_template1.format(
        angle_format=angle_format, actual_angle_format=actual_angle_format, mtl_format=mtl_format)


def gen_image_map_switch_mac_case(angle_format, actual_angle_format, angle_to_mtl_map,
                                  mac_specific_map, mac_fallbacks):
    if actual_angle_format in mac_specific_map:
        # look for the metal format in mac specific table
        mtl_format = mac_specific_map[actual_angle_format]
    else:
        # look for the metal format in common table
        mtl_format = angle_to_mtl_map[actual_angle_format]

    if actual_angle_format in mac_fallbacks:
        # This format requires fallback when depth24Stencil8PixelFormatSupported flag is false.
        # Fallback format:
        actual_angle_format_fallback = mac_fallbacks[actual_angle_format]
        if actual_angle_format_fallback in mac_specific_map:
            # look for the metal format in mac specific table
            mtl_format_fallback = mac_specific_map[actual_angle_format_fallback]
        else:
            # look for the metal format in common table
            mtl_format_fallback = angle_to_mtl_map[actual_angle_format_fallback]
        # return if else block:
        return case_image_format_template2.format(
            angle_format=angle_format,
            actual_angle_format=actual_angle_format,
            mtl_format=mtl_format,
            actual_angle_format_fallback=actual_angle_format_fallback,
            mtl_format_fallback=mtl_format_fallback)
    else:
        # return ordinary block:
        return case_image_format_template1.format(
            angle_format=angle_format,
            actual_angle_format=actual_angle_format,
            mtl_format=mtl_format)


def gen_image_map_switch_string(image_table):
    angle_override = image_table["override"]
    mac_override = image_table["override_mac"]
    ios_override = image_table["override_ios"]
    mac_fallbacks = image_table["fallbacks_mac"]
    angle_to_mtl = image_table["map"]
    mac_specific_map = image_table["map_mac"]
    ios_specific_map = image_table["map_ios"]

    switch_data = ''

    def gen_image_map_switch_common_case(angle_format, actual_angle_format):
        mac_case = gen_image_map_switch_mac_case(angle_format, actual_angle_format, angle_to_mtl,
                                                 mac_specific_map, mac_fallbacks)
        non_mac_case = gen_image_map_switch_simple_case(angle_format, actual_angle_format,
                                                        angle_to_mtl)
        if mac_case == non_mac_case:
            return mac_case

        re = ''
        re += "#if TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
        re += mac_case
        re += "#else  // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
        re += non_mac_case
        re += "#endif  // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
        return re

    # Common case
    for angle_format in sorted(angle_to_mtl.keys()):
        switch_data += gen_image_map_switch_common_case(angle_format, angle_format)
    for angle_format in sorted(angle_override.keys()):
        switch_data += gen_image_map_switch_common_case(angle_format, angle_override[angle_format])

    # Mac specific
    switch_data += "#if TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
    for angle_format in sorted(mac_specific_map.keys()):
        switch_data += gen_image_map_switch_mac_case(angle_format, angle_format, angle_to_mtl,
                                                     mac_specific_map, mac_fallbacks)
    for angle_format in sorted(mac_override.keys()):
        # overide case will always map to a format in common table, i.e. angle_to_mtl
        switch_data += gen_image_map_switch_mac_case(angle_format, mac_override[angle_format],
                                                     angle_to_mtl, mac_specific_map, mac_fallbacks)

    # iOS specific
    switch_data += "#elif TARGET_OS_IOS  // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
    for angle_format in sorted(ios_specific_map.keys()):
        switch_data += gen_image_map_switch_simple_case(angle_format, angle_format,
                                                        ios_specific_map)
    for angle_format in sorted(ios_override.keys()):
        # overide case will always map to a format in common table, i.e. angle_to_mtl
        switch_data += gen_image_map_switch_simple_case(angle_format, ios_override[angle_format],
                                                        angle_to_mtl)
    switch_data += "#endif  // TARGET_OS_OSX || TARGET_OS_MACCATALYST\n"
    switch_data += "        default:\n"
    switch_data += "            this->metalFormat = MTLPixelFormatInvalid;\n"
    switch_data += "            this->actualFormatId = angle::FormatID::NONE;"
    return switch_data


def gen_vertex_map_switch_case(angle_fmt, actual_angle_fmt, angle_to_mtl_map, override_packed_map):
    mtl_format = angle_to_mtl_map[actual_angle_fmt]
    copy_function = angle_format.get_vertex_copy_function(angle_fmt, actual_angle_fmt)
    if actual_angle_fmt in override_packed_map:
        # This format has an override when used in tightly packed buffer,
        # Return if else block
        angle_fmt_packed = override_packed_map[actual_angle_fmt]
        mtl_format_packed = angle_to_mtl_map[angle_fmt_packed]
        copy_function_packed = angle_format.get_vertex_copy_function(angle_fmt, angle_fmt_packed)
        return case_vertex_format_template2.format(
            angle_format=angle_fmt,
            mtl_format_packed=mtl_format_packed,
            actual_angle_format_packed=angle_fmt_packed,
            vertex_copy_function_packed=copy_function_packed,
            mtl_format=mtl_format,
            actual_angle_format=actual_angle_fmt,
            vertex_copy_function=copy_function)
    else:
        # This format has no packed buffer's override, return ordinary block.
        return case_vertex_format_template1.format(
            angle_format=angle_fmt,
            mtl_format=mtl_format,
            actual_angle_format=actual_angle_fmt,
            vertex_copy_function=copy_function)


def gen_vertex_map_switch_string(vertex_table):
    angle_to_mtl = vertex_table["map"]
    angle_override = vertex_table["override"]
    override_packed = vertex_table["override_tightly_packed"]

    switch_data = ''
    for angle_fmt in sorted(angle_to_mtl.keys()):
        switch_data += gen_vertex_map_switch_case(angle_fmt, angle_fmt, angle_to_mtl,
                                                  override_packed)

    for angle_fmt in sorted(angle_override.keys()):
        switch_data += gen_vertex_map_switch_case(angle_fmt, angle_override[angle_fmt],
                                                  angle_to_mtl, override_packed)

    switch_data += "        default:\n"
    switch_data += "            this->metalFormat = MTLVertexFormatInvalid;\n"
    switch_data += "            this->actualFormatId = angle::FormatID::NONE;\n"
    switch_data += "            this->vertexLoadFunction = nullptr;"
    return switch_data


def main():
    # auto_script parameters.
    if len(sys.argv) > 1:
        inputs = ['mtl_format_map.json']
        outputs = ['mtl_format_table_autogen.mm']

        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

    data_source_name = 'mtl_format_map.json'
    map_json = angle_format.load_json(data_source_name)
    map_image = map_json["image"]
    map_vertex = map_json["vertex"]

    image_switch_data = gen_image_map_switch_string(map_image)

    vertex_switch_data = gen_vertex_map_switch_string(map_vertex)

    output_cpp = template_autogen_inl.format(
        script_name=sys.argv[0],
        copyright_year=date.today().year,
        data_source_name=data_source_name,
        angle_image_format_switch=image_switch_data,
        angle_vertex_format_switch=vertex_switch_data)
    with open('mtl_format_table_autogen.mm', 'wt') as out_file:
        out_file.write(output_cpp)
        out_file.close()


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