#! /usr/bin/python3

# Copyright 2022 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_features.py:
#  Code generation for ANGLE features.
#  NOTE: don't run this script directly. Run scripts/run_code_generation.py.

from collections import namedtuple
import json
import os
import re
import sys

feature_files = {
    'd3d_features.json': ('D3D', 'FeaturesD3D'),
    'frontend_features.json': ('Frontend', 'FrontendFeatures'),
    'gl_features.json': ('OpenGL', 'FeaturesGL'),
    'mtl_features.json': ('Metal', 'FeaturesMtl'),
    'vk_features.json': ('Vulkan', 'FeaturesVk'),
    'wgpu_features.json': ('WebGPU', 'FeaturesWgpu'),
}
feature_list_header_file = '../../util/autogen/angle_features_autogen.h'
feature_list_source_file = '../../util/autogen/angle_features_autogen.cpp'

template_header = u"""// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {input_file_name}.
//
{description}

#ifndef ANGLE_PLATFORM_AUTOGEN_{NAME}_H_
#define ANGLE_PLATFORM_AUTOGEN_{NAME}_H_

#include "platform/Feature.h"

namespace angle
{{

struct {name} : FeatureSetBase
{{
    {name}();
    ~{name}();

{features}
}};

inline {name}::{name}()  = default;
inline {name}::~{name}() = default;

}}  // namespace angle

#endif  // ANGLE_PLATFORM_AUTOGEN_{NAME}_H_
"""

template_feature = u"""    FeatureInfo {var_name} = {{
        "{display_name}",
        FeatureCategory::{category},
        &members,
    }};
"""

template_feature_list_header = u"""// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {input_file_name}.
//
// Copyright 2022 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.
//
// angle_features_autogen.h: List of ANGLE features to help enable/disable them in tests.

#ifndef ANGLE_SRC_TESTS_TEST_UTIL_AUTOGEN_ANGLE_FEATURES_AUTOGEN_H_
#define ANGLE_SRC_TESTS_TEST_UTIL_AUTOGEN_ANGLE_FEATURES_AUTOGEN_H_

#include "../util_export.h"

namespace angle
{{
enum class Feature
{{
{features}

    InvalidEnum,
    EnumCount = InvalidEnum,
}};

ANGLE_UTIL_EXPORT extern const char *GetFeatureName(Feature feature);

}}  // namespace angle

#endif  // ANGLE_SRC_TESTS_TEST_UTIL_AUTOGEN_ANGLE_FEATURES_AUTOGEN_H_
"""

template_feature_enum = u"""{VarName},"""

template_feature_list_source = u"""// GENERATED FILE - DO NOT EDIT.
// Generated by {script_name} using data from {input_file_name}.
//
// Copyright 2022 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.
//
// angle_features_autogen.cpp: List of ANGLE features to help enable/disable them in tests.

#include "angle_features_autogen.h"

#include "common/PackedEnums.h"

namespace angle
{{
namespace
{{
constexpr PackedEnumMap<Feature, const char *> kFeatureNames = {{{{
{features}
}}}};
}}  // anonymous namespace

const char *GetFeatureName(Feature feature)
{{
    return kFeatureNames[feature];
}}

}}  // namespace angle
"""

template_feature_string = u"""    {{Feature::{VarName}, "{display_name}"}},"""


def make_camel_case(json_name):
    assert '_' in json_name, 'feature names in the json file are expected to be in snake_case'
    return re.sub('_(.)', lambda m: m.group(1).upper(), json_name)


def make_header_name(class_name):
    return class_name + '_autogen.h'


def header_path(class_name):
    return 'autogen/' + make_header_name(class_name)


def write_or_verify_file(filename, content, verify_only):
    if verify_only:
        try:
            with open(filename) as f:
                # Note: .gitattributes "* text=auto" handles LF <-> CRLF on Windows
                return f.read() == content
        except FileNotFoundError:
            return False
    else:
        with open(filename, 'w') as fout:
            fout.write(content)
            return True


def main():
    if len(sys.argv) == 2 and sys.argv[1] == 'inputs':
        print(','.join(list(feature_files.keys())))
        return
    if len(sys.argv) == 2 and sys.argv[1] == 'outputs':
        print(','.join([header_path(class_name) for (_, class_name) in feature_files.values()]) +
              ',' + feature_list_header_file + ',' + feature_list_source_file)
        return

    # --verify-only enables dirty checks without relying on checked in hashes.
    # Compares the content of the existing file with the generated content.
    verify_only = '--verify-only' in sys.argv

    name_map = {}

    for src_file, (category_prefix, class_name) in feature_files.items():
        with open(src_file) as fin:
            src = json.loads(fin.read())

        features_json = src['features']
        features = []

        # Go over the list of features and write the header file that declares the features struct
        for feature_json in features_json:
            json_name = feature_json['name']
            var_name = make_camel_case(json_name)
            # Use the same (camelCase) name for display as well
            display_name = var_name
            feature = template_feature.format(
                var_name=var_name,
                display_name=display_name,
                category=category_prefix + feature_json['category'])

            features.append(feature)

            # Keep track of the feature names.  Sometimes the same feature name is present in
            # multiple backends.  That's ok for the purposes of feature overriding.
            name_map[var_name] = display_name

        description = '\n'.join(
            ['//' + (' ' + line if line else '') for line in src['description']])
        header_file = make_header_name(class_name)

        header = template_header.format(
            script_name=os.path.basename(__file__),
            input_file_name=src_file,
            description=description.replace(src_file, header_file),
            name=class_name,
            NAME=class_name.upper(),
            features='\n'.join(features))

        if not write_or_verify_file(header_path(class_name), header, verify_only):
            return 1

    # Generate helpers for use by tests to override a feature or not.
    feature_enums = []
    feature_strings = []
    for var_name, display_name in sorted(name_map.items(), key=lambda item: item[0].lower()):
        VarName = var_name[0].upper() + var_name[1:]

        feature_enums.append(template_feature_enum.format(VarName=VarName))

        feature_strings.append(
            template_feature_string.format(VarName=VarName, display_name=display_name))

    if not write_or_verify_file(
            feature_list_header_file,
            template_feature_list_header.format(
                script_name=os.path.basename(__file__),
                input_file_name='*_features.json',
                features='\n'.join('    ' + v for v in feature_enums)), verify_only):
        return 1

    if not write_or_verify_file(
            feature_list_source_file,
            template_feature_list_source.format(
                script_name=os.path.basename(__file__),
                input_file_name='*_features.json',
                features='\n'.join(feature_strings)), verify_only):
        return 1


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