#!/usr/bin/env python
# coding: utf-8
# 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 json
from pathlib import Path
from textwrap import indent
import logging

from jsonschema import validate, ValidationError 


def validate_container_flags(config):
    """校验 wsl_enabled 和 docker_enabled 最多一个为 True"""
    container_cfg = config["container_cfg"]
    if container_cfg["wsl_enabled"] and container_cfg["docker_enabled"]:
        raise ValueError("wsl_enabled 和 docker_enabled 不能同时为 True")
    if not container_cfg["docker_enabled"] and "docker_num" in container_cfg:
        logging.error("警告: docker未启用但设置了docker_num，将忽略此配置")


def load_config(config_path, schema_path):
    try:
        with open(config_path) as f:
            config = json.load(f)
        
        with open(schema_path) as f:
            schema = json.load(f)
        
        # 基础 Schema 校验
        validate(instance=config, schema=schema)
        
        # 自定义逻辑校验
        validate_container_flags(config)
        
        # 自动创建 qemu_setup_dir
        qemu_dir = Path(config["start_dependencies"]["qemu_setup_dir"])
        qemu_dir.mkdir(parents=True, exist_ok=True)
        
        # 检查文件是否存在（如果路径非空）
        for file_key in ["cpio_path", "zImage_path"]:
            file_path = config["start_dependencies"][file_key]
            if file_path and not Path(file_path).is_file():
                logging.warning(f"警告: {file_key} 文件不存在: {file_path}")
                logging.warning("可通过构建manifest或者下载方式获取，本次采用下载方式")
            else:
                config["start_dependencies"][file_key] = file_path
        return config
    
    except (FileNotFoundError, json.JSONDecodeError, ValidationError) as e:
        logging.error(f"配置验证失败: {type(e).__name__}: {e}")
        raise


def print_config(config):
    """以友好格式打印配置信息"""
    # 检查容器配置冲突
    container_cfg = config["container_cfg"]
    conflict_msg = ""
    if container_cfg["wsl_enabled"] and container_cfg["docker_enabled"]:
        conflict_msg = "冲突！wsl_enabled和docker_enabled不能同时为True"
    
    # 检查文件是否存在
    files_status = {}
    for file_key in ["cpio_path", "zImage_path"]:
        path = config["start_dependencies"][file_key]
        if not path:
            files_status[file_key] = "未设置"
        else:
            files_status[file_key] = "存在" if Path(path).exists() else f"缺失 ({path})"

    qemu_cfg = config["qemu_cfg"]
    # 构建输出信息
    output = [
        "=== 配置摘要 ===",
        "",
        "1. 端口映射:",
        *indent(json.dumps(config["mapports"], indent=2), " ").split('\n'),
        "",
        "2. 启动依赖:",
        f"  • QEMU临时目录: {config['start_dependencies']['qemu_setup_dir']}",
        f"  • CPIO文件: {files_status.get('cpio_path', '未找到')}",
        f"  • zImage文件: {files_status.get('zImage_path', '未找到')}",
        f"  • DTB文件: {config['start_dependencies']['dtb']}",
        f"  • Qemu工具是否从远端下载: {config['start_dependencies']['remote_qemu']}",
        f"  • Qemu仿真镜像是否从远端下载: {config['start_dependencies']['remote_cpio']}",
        "",
        "3. 容器配置:",
        f"  • 容器版本: {container_cfg['container']}",
        f"  • WSL启用: {container_cfg['wsl_enabled']}",
        f"  • Docker启用: {container_cfg['docker_enabled']}",
    ]

    # 添加docker_num信息（如果启用）
    if container_cfg["docker_enabled"]:
        output.append(f"  • 容器实例数: {container_cfg.get('docker_num', 1)}")
        output.append(f"  • 容器操作: {container_cfg.get('docker_operator', 1)}")
        output.append(f"  • 容器镜像地址: {container_cfg.get('docker_image', '')}")

    output.extend([
        "",
        "4. Qemu配置:",
        f"  • Qemu仿真cpu核数: {qemu_cfg.get('core_num', -1)}",
        f"  • Qemu仿真内存: {qemu_cfg.get('memory', -1)}GB"
    ])

    # 添加检查结果
    if conflict_msg:
        output.extend(["", "检查结果:", conflict_msg])
    else:
        output.append("\n=== ✓ 所有配置校验通过 ===")
    
    # 打印结果
    logging.warning("\n".join(output))