#!/usr/bin/env python
# Copyright (c) 2024 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 os
import shutil
import json
import sys
import copy
import re
import subprocess
from conan.tools.files import chdir
from conan.tools.files import copy
from conanbase import ConanBase

required_conan_version = ">=1.60.0"


class AppConan(ConanBase):
    def build(self):
        if self.settings.build_type == "Release":
            with chdir(self, self.source_folder):
                self.run("rm -rf ./interface_config/cli/ipmcset/dft.json")
                self.run("rm -rf ./interface_config/cli/ipmcget/dft.json")
        super(AppConan, self).build()
        
        with chdir(self, self.source_folder):
            sys.path.append(self.source_folder)
            from mapper_check import MapperCheck
            MapperCheck.check()
            from schema_check.schema_checker import SchemaChecker
            sc = SchemaChecker()
            sc.check()
        
    def custom_ipmc_version(self):
        bmc_name = str(self.options.bmc_name)
        if bmc_name:
            ipmc_version = os.path.join(self.source_folder, "interface_config/cli/echoes/ipmcget/_version")
            with open(ipmc_version, "r") as fp:
                data = fp.read()
            data = data.replace("openUBMC INFO", f"{bmc_name} INFO")
            new_bmc = bmc_name.ljust(len("openUBMC"))
            data = re.sub(r"\bopenUBMC\b", new_bmc, data)
            with open(ipmc_version, "w") as fp:
                fp.write(data)
    
    def read_config(self):
        config_path = os.path.join(self.source_folder, "interface_config/redfish/config.json")
        with open(config_path, 'r') as file:
            config = json.load(file)
        # 获取SoftwareName和SmsName的值,如果没有配置则使用默认值
        software_name = config.get('GlobalVariable', {}).get('SoftwareName', 'openUBMC')
        sms_name = config.get('GlobalVariable', {}).get('SmsName', 'BMA')
        return software_name, sms_name

    def replace_strings_in_files(self, software_name, sms_name):
        schemastore_path = os.path.join(self.source_folder,
                                        "interface_config/redfish/static_resource/redfish/v1/schemastore/en")
        for root, _, files in os.walk(schemastore_path):
            for filename in files:
                if filename.endswith('.json'):
                    file_path = os.path.join(root, filename)
                    with open(file_path, 'r') as file:
                        content = file.read()
                    # 批量字段替换
                    content = content.replace('{{SoftwareName}}', software_name)
                    content = content.replace('{{SmsName}}', sms_name)
                    # 写回静态文件
                    with open(file_path, 'w') as file:
                        file.write(content)

    def package(self):
        copy(self, "permissions.ini", src=os.path.join(self.source_folder, "dist"), dst=self.package_folder)
        self.custom_ipmc_version()
        software_name, sms_name = self.read_config()
        self.replace_strings_in_files(software_name, sms_name)

        super(AppConan, self).package()
        sys.path.append(self.source_folder)
        from  custom import mapping_config_patch
        
        # 各个接口的Script和Plugins配置文件需要保持文本形式,避免探测关联属性失败以及映射器批量替换字段失败
        interface = {"redfish", "web_backend", "cli", "snmp"}
        for intf in interface:
            lua_dir = os.path.join(self.source_folder, "interface_config/" + intf)
            lua_package_dir = os.path.join(self.package_folder, "opt/bmc/apps/" + intf + "/interface_config")
            for root, dirs, files in os.walk(lua_dir):
                for file in files:
                    if file.endswith(".lua") and not os.path.islink(file):
                        file_path = os.path.join(root, file)
                        file_package_path = file_path.replace(lua_dir, lua_package_dir)
                        shutil.copy2(file_path, file_package_path)
            config_path = os.path.join(self.source_folder, 'interface_config', intf)
            patch_path = os.path.join(self.source_folder, 'oem', str(self.options.oem), intf)
            if not os.path.isdir(patch_path):
                continue
            map_patch = mapping_config_patch.MappingConfigPatch(self, patch_path, config_path)
            map_patch.run()

        # 支持装备测试正向采集
        for intf in ["board_info_collector"]:
            lua_dir = os.path.join(self.source_folder, "interface_config/" + intf)
            lua_package_dir = os.path.join(self.package_folder, "opt/bmc/board_info_collector")
            if not os.path.exists(lua_package_dir):
                os.mkdir(lua_package_dir)
            for root, dirs, files in os.walk(lua_dir):
                for file in files:
                    if file.endswith(".lua") and not os.path.islink(file):
                        file_path = os.path.join(root, file)
                        file_package_path = file_path.replace(lua_dir, lua_package_dir)
                        result =os.path.split(file_package_path)
                        if not os.path.exists(result[0]):
                            os.mkdir(result[0])
                        shutil.copy2(file_path, file_package_path)
            config_path = os.path.join(self.source_folder, 'interface_config', intf)
            patch_path = os.path.join(self.source_folder, 'oem', str(self.options.oem), intf)
            if not os.path.isdir(patch_path):
                continue
            map_patch = mapping_config_patch.MappingConfigPatch(self, patch_path, config_path)
            map_patch.run()

        # 压缩json文件
        config_dir = os.path.join(self.source_folder, "interface_config")
        for root, dirs, files in os.walk(config_dir):
            for file in files:
                if file.endswith(".json") and not os.path.islink(file):
                    file_path = os.path.join(root, file)
                    with open(file_path, mode='rb') as fp:
                        data = json.load(fp)
                    content = json.dumps(data, separators=(',', ':'))
                    with open(file_path, mode='wb') as fd:
                        fd.write(content.encode('utf-8'))
                    for interface_type in ["web_backend", "redfish", "snmp", "cli"]:
                        if "interface_config/" + interface_type in file_path:
                            json_dir = os.path.join(self.source_folder, "interface_config", interface_type)
                            json_package_dir = os.path.join(self.package_folder, "opt/bmc/apps", interface_type, "interface_config")
                    for interface_type in ["board_info_collector"]:
                        if "interface_config/" + interface_type in file_path:
                            json_dir = os.path.join(self.source_folder, "interface_config", interface_type)
                            json_package_dir = os.path.join(self.package_folder, "opt/bmc/board_info_collector")
                    file_package_path = file_path.replace(json_dir, json_package_dir)                    
                    result =os.path.split(file_package_path)
                    if not os.path.exists(result[0]):
                        os.mkdir(result[0])
                    shutil.copy2(file_path, file_package_path)

    def package_info(self):
        pass