#!/usr/bin/env python
# coding=utf-8
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
# openUBMC is licensed under Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#         http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
# EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
# MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
# See the Mulan PSL v2 for more details.
import json
import os
import sys
import logging
import argparse
from typing import Dict, Any


def deep_merge(a: Dict[str, Any], b: Dict[str, Any]) -> Dict[str, Any]:
    """
    深度合并两个字典，处理各种类型的属性
    :param a: 第一个字典
    :param b: 第二个字典
    :return: 合并后的字典
    """
    result = a.copy()

    for key, value in b.items():
        if key in result:
            # 如果两个字典都有这个key
            if isinstance(result[key], dict) and isinstance(value, dict):
                # 如果两个值都是字典，递归合并
                result[key] = deep_merge(result[key], value)
            elif isinstance(result[key], list) and isinstance(value, list):
                # 如果两个值都是列表，合并列表
                result[key] = result[key] + value
            else:
                # 其他情况（数字、字符串、不同类型等），用b的值覆盖a的值
                result[key] = value
        else:
            # 如果a没有这个key，直接添加
            result[key] = value

    return result


def merge_json_files(base_file: str, file_b: str, output_file: str = None):
    """
    合并两个JSON文件
    :param base_file: 第一个JSON文件路径
    :param file_b: 第二个JSON文件路径
    :param output_file: 可选，输出文件路径
    :return: 合并后的字典
    """
    with open(base_file, 'r', encoding='utf-8') as f:
        data_a = json.load(f)

    with open(file_b, 'r', encoding='utf-8') as f:
        data_b = json.load(f)

    merged_data = deep_merge(data_a, data_b)

    with open(output_file, 'w', encoding='utf-8') as f:
        json.dump(merged_data, f, ensure_ascii=False, indent=2)


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description='merge json files', formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument("-s", "--source_dir", help="源目录", required=True)
    parser.add_argument("-p", "--patch_dir", help="补丁目录", required=True)
    parser.add_argument("-o", "--output_dir", help="输出目录", required=True)
    args = parser.parse_args()
    if not os.path.isdir(args.source_dir):
        logging.info("source dir '{args.source_dir}'not exist")
        sys.exit(-1)
    if not os.path.isdir(args.patch_dir):
        logging.info("patch dir '{args.patch_dir}' not exist")
        sys.exit(-1)
    if not os.path.isdir(args.output_dir):
        logging.info("output dir '{args.output_dir}' not exist")
        sys.exit(-1)

    for file in os.listdir(args.patch_dir):
        if not file.endswith(".schema.patch.json"):
            continue
        patch_file = os.path.join(args.patch_dir, file)
        dst_filename = file.replace(".schema.patch.json", ".schema.json")
        src_file = os.path.join(args.source_dir, dst_filename)
        dst_file = os.path.join(args.output_dir, dst_filename)
        if not os.path.exists(src_file):
            logging.info(f"file {dst_file} not exists, skip merge")
            continue
        logging.info(f"start merge {patch_file} and {src_file}, output is {dst_file}")
        merge_json_files(src_file, patch_file, dst_file)
