#!/usr/bin/env python3
# Copyright 2025 Espressif Systems (Shanghai) PTE LTD
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Script to generate files under cluster_select directory, please run this script
after updating connectedhomeip submodule
"""

import argparse
import json
import os
import pathlib
import logging
import sys

if not os.getenv('ESP_MATTER_PATH'):
    logging.error("ESP_MATTER_PATH environment variable is not set")
    sys.exit(1)

BASE_PATH = os.getenv('ESP_MATTER_PATH')


def write_file_header(file):
    file.writelines(
        ['# This file is generated by {}\n'.format(os.path.basename(__file__)),
         '# Please don\'t edit this file\n'
         '\n'])


def load_json(json_file):
    with open(json_file, 'r', encoding='utf-8') as file:
        data = json.load(file)
    server_dirs = data.get("ServerDirectories", {})
    return {key: value for key, value in server_dirs.items() if value}


# Clusters that require OpenThread support
OPENTHREAD_CLUSTERS = {
    'THREAD_BORDER_ROUTER_MANAGEMENT_CLUSTER',
    'THREAD_NETWORK_DIAGNOSTICS_CLUSTER',
    'THREAD_NETWORK_DIRECTORY_CLUSTER',
}


def generate_cluster_select_kconfig(cluster_list, output_dir):
    with open(os.path.join(output_dir, 'Kconfig.in'), 'w') as kconfig_file:
        write_file_header(kconfig_file)
        for cluster in cluster_list.keys():
            lines = [f'config SUPPORT_{cluster}\n',
                     f'\tbool "Support {cluster}"\n']
            if cluster in OPENTHREAD_CLUSTERS:
                lines.append('\tdepends on OPENTHREAD_ENABLED\n')
            lines.append('\tdefault y\n')
            lines.append('\n')
            kconfig_file.writelines(lines)


def generate_cluster_select_cmake(cluster_list, output_dir):
    with open(os.path.join(output_dir, 'cluster_dir.cmake'), 'w') as cmake_file:
        write_file_header(cmake_file)
        cmake_file.write('function(get_supported_cluster_dirs source_dirs)\n')
        cmake_file.write('\tset(temp_list )\n')
        for cluster, dirs in cluster_list.items():
            cmake_file.write(f'\tif(CONFIG_SUPPORT_{cluster})\n')
            for dir in dirs:
                cmake_file.write(f'\t\tlist(APPEND temp_list "${{MATTER_SDK_PATH}}/src/app/clusters/{dir}")\n')

            cmake_file.write('\tendif()\n')

        cmake_file.write('\tset(${source_dirs} ${temp_list} PARENT_SCOPE)\n')
        cmake_file.write('endfunction()')


def main():
    parser = argparse.ArgumentParser()
    parser.add_argument('--cluster-implementation-data',
                        help='Path to .json file which lists the directories cluster implementations live in',
                        required=False,
                        type=pathlib.Path,
                        default=os.path.join(
                            BASE_PATH, 'connectedhomeip/connectedhomeip/src/app/zap_cluster_list.json'))
    parser.add_argument('-o', '--output-dir',
                        default=os.path.join(
                            BASE_PATH, 'components/esp_matter/utils/cluster_select'),
                        help='The output directory')
    args = parser.parse_args()

    cluster_list = load_json(args.cluster_implementation_data)
    generate_cluster_select_kconfig(cluster_list, args.output_dir)
    generate_cluster_select_cmake(cluster_list, args.output_dir)


if __name__ == "__main__":
    main()
