#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
系统配置模块
提供集中的配置管理，支持开发环境、测试环境和生产环境
"""

import os
from typing import Dict, Any, Optional, List
from pydantic import Field
from pydantic_settings import BaseSettings

# 定义数据目录路径
DATA_DIR = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "data")
# 确保数据目录存在
os.makedirs(DATA_DIR, exist_ok=True)

# 服务器配置
default_server_config = {
    'host': '0.0.0.0',
    'port': 8000,
    'workers': 1,
    'reload': True,
    'log_level': 'info'
}

production_server_config = {
    'host': '0.0.0.0',
    'port': 8000,
    'workers': 4,
    'reload': False,
    'log_level': 'warning'
}

test_server_config = {
    'host': '127.0.0.1',
    'port': 8001,
    'workers': 1,
    'reload': False,
    'log_level': 'debug'
}

# 数据库配置
default_db_config = {
    'dialect': 'mysql',
    'driver': 'pymysql',
    'username': 'root',
    'password': 'root',
    'host': 'localhost',
    'port': 3306,
    'database': 'vwed_task',
    'charset': 'utf8mb4'
}

# Redis配置
default_redis_config = {
    'host': 'localhost',
    'port': 6379,
    'db': 0,
    'password': None,
    'prefix': 'vwed:',
    'socket_timeout': 5,
    'socket_connect_timeout': 5,
    'decode_responses': True
}

test_redis_config = {
    'host': 'localhost',
    'port': 6379,
    'db': 1,
    'password': None,
    'prefix': 'vwed_test:',
    'decode_responses': True
}

# 库位服务API端点映射
storage_api_endpoints = {
    "batch_setting_site": "/site/batch-setting",
    "get_idle_crowded_site": "/site/idle-crowded",
    "get_idle_site": "/site/idle",
    "get_locked_sites_by_task_record_id": "/site/locked-by-task",
    "get_site_attr": "/site/attr",
    "query_idle_site": "/site/query",
    "set_site_attr": "/site/attr",
    "set_site_content": "/site/content",
    "set_site_empty": "/site/empty",
    "set_site_filled": "/site/filled",
    "set_site_locked": "/site/lock",
    "set_site_tags": "/site/tags",
    "set_site_unlocked": "/site/unlock"
}

# 库位服务API HTTP方法映射
storage_api_methods = {
    "batch_setting_site": "POST",
    "get_idle_crowded_site": "GET",
    "get_idle_site": "GET",
    "get_locked_sites_by_task_record_id": "GET",
    "get_site_attr": "GET",
    "query_idle_site": "GET",
    "set_site_attr": "PUT",
    "set_site_content": "PUT",
    "set_site_empty": "PUT",
    "set_site_filled": "PUT",
    "set_site_locked": "PUT",
    "set_site_tags": "PUT",
    "set_site_unlocked": "PUT"
}

# 机器人调度服务API端点映射
robot_api_endpoints = {
    "vehicle_station": "/robot/station",
    "get_battery_level": "/robot/battery",
    "get_pgv_code": "/robot/pgv-code"
}

# 机器人调度服务API HTTP方法映射
robot_api_methods = {
    "vehicle_station": "GET",
    "get_battery_level": "GET",
    "get_pgv_code": "GET"
}

# 外部服务API配置
external_api_config = {
    "storage": {
        "base_url": "http://localhost:8080/api/storage",
        "endpoints": storage_api_endpoints,
        "methods": storage_api_methods
    },
    "robot": {
        "base_url": "http://localhost:8080/api/robot",
        "endpoints": robot_api_endpoints,
        "methods": robot_api_methods
    }
}

def get_config_for_env(env: str, config_type: str) -> Dict[str, Any]:
    """根据环境获取配置"""
    if config_type == 'server':
        if env == 'production':
            return production_server_config
        elif env == 'test':
            return test_server_config
        return default_server_config
    
    elif config_type == 'db':
        # 目前只有默认数据库配置
        return default_db_config
    
    elif config_type == 'redis':
        if env == 'test':
            return test_redis_config
        return default_redis_config
    
    return {}


class BaseConfig(BaseSettings):
    """基础配置类"""
    # 应用信息
    APP_NAME: str = "VWED任务系统"
    APP_VERSION: str = "1.0.0"
    APP_DESCRIPTION: str = "自动化移动机器人(AMR)任务管理系统"
    
    # 系统设置
    DEBUG: bool = False
    API_PREFIX: str = "/api"
    
    # 获取当前环境
    _env: str = os.getenv("APP_ENV", "development").lower()
    
    # 服务配置
    _server_config = get_config_for_env(_env, 'server')
    SERVER_HOST: str = Field(default=_server_config['host'], env="HOST")
    SERVER_PORT: int = Field(default=_server_config['port'], env="PORT")
    SERVER_WORKERS: int = Field(default=_server_config['workers'], env="WORKERS")
    SERVER_RELOAD: bool = Field(default=_server_config['reload'], env="RELOAD")
    SERVER_LOG_LEVEL: str = Field(default=_server_config['log_level'], env="LOG_LEVEL")
    
    # Modbus设备配置
    MODBUS_MOCK_MODE: bool = Field(default=True, env="MODBUS_MOCK_MODE")  # 测试模式：True表示启用模拟数据
    MODBUS_TIMEOUT: float = Field(default=2.0, env="MODBUS_TIMEOUT")     # Modbus通信超时时间（秒）
    MODBUS_RETRY_INTERVAL: float = Field(default=1.0, env="MODBUS_RETRY_INTERVAL")  # 重试间隔时间（秒）
    MODBUS_POLL_INTERVAL: float = Field(default=0.5, env="MODBUS_POLL_INTERVAL")   # 轮询间隔时间（秒）
    
    # 数据库连接配置
    _db_config = get_config_for_env(_env, 'db')
    DB_DIALECT: str = Field(default=_db_config['dialect'], env="DB_DIALECT")
    DB_DRIVER: str = Field(default=_db_config['driver'], env="DB_DRIVER")
    DB_USER: str = Field(default=_db_config['username'], env="DB_USER")
    DB_PASSWORD: str = Field(default=_db_config['password'], env="DB_PASSWORD")
    DB_HOST: str = Field(default=_db_config['host'], env="DB_HOST")
    DB_PORT: str = Field(default=str(_db_config['port']), env="DB_PORT")
    DB_NAME: str = Field(default=_db_config['database'], env="DB_NAME")
    DB_CHARSET: str = Field(default=_db_config['charset'], env="DB_CHARSET")
    DB_ECHO: bool = False  # 是否输出SQL语句
    DB_POOL_SIZE: int = 10
    DB_MAX_OVERFLOW: int = 20
    DB_POOL_RECYCLE: int = 3600  # 连接池回收时间，防止连接过期
    
    # Redis配置
    _redis_config = get_config_for_env(_env, 'redis')
    REDIS_HOST: str = Field(default=_redis_config['host'], env="REDIS_HOST")
    REDIS_PORT: int = Field(default=_redis_config['port'], env="REDIS_PORT")
    REDIS_DB: int = Field(default=_redis_config['db'], env="REDIS_DB")
    REDIS_PASSWORD: Optional[str] = Field(default=_redis_config['password'], env="REDIS_PASSWORD")
    REDIS_PREFIX: str = Field(default=_redis_config['prefix'], env="REDIS_PREFIX")
    REDIS_SOCKET_TIMEOUT: int = Field(default=_redis_config['socket_timeout'], env="REDIS_SOCKET_TIMEOUT")
    REDIS_SOCKET_CONNECT_TIMEOUT: int = Field(default=_redis_config['socket_connect_timeout'], env="REDIS_SOCKET_CONNECT_TIMEOUT")
    REDIS_DECODE_RESPONSES: bool = Field(default=_redis_config['decode_responses'], env="REDIS_DECODE_RESPONSES")
    
    # 安全设置
    SECRET_KEY: str = Field(default="YOUR_SECRET_KEY_HERE", env="SECRET_KEY")
    ACCESS_TOKEN_EXPIRE_MINUTES: int = 60 * 24  # 1天
    
    # 外部服务API通用配置
    API_TIMEOUT: int = Field(default=30, env="API_TIMEOUT")  # 请求超时时间（秒）
    API_TOKEN: Optional[str] = Field(default=None, env="API_TOKEN")  # API通用认证令牌
    API_MOCK_MODE: bool = Field(default=False, env="API_MOCK_MODE")  # 是否启用API模拟模式
    
    # 库位服务API配置
    STORAGE_API_BASE_URL: str = Field(default=external_api_config["storage"]["base_url"], env="STORAGE_API_BASE_URL")
    STORAGE_API_ENDPOINTS: Dict[str, str] = external_api_config["storage"]["endpoints"]
    STORAGE_API_METHODS: Dict[str, str] = external_api_config["storage"]["methods"]
    STORAGE_API_TIMEOUT: int = Field(default=30, env="STORAGE_API_TIMEOUT")
    STORAGE_API_TOKEN: Optional[str] = Field(default=None, env="STORAGE_API_TOKEN")
    STORAGE_API_MOCK_MODE: bool = Field(default=False, env="STORAGE_API_MOCK_MODE")
    
    # 机器人调度服务API配置
    ROBOT_API_BASE_URL: str = Field(default=external_api_config["robot"]["base_url"], env="ROBOT_API_BASE_URL")
    ROBOT_API_ENDPOINTS: Dict[str, str] = external_api_config["robot"]["endpoints"]
    ROBOT_API_METHODS: Dict[str, str] = external_api_config["robot"]["methods"]
    ROBOT_API_TIMEOUT: int = Field(default=30, env="ROBOT_API_TIMEOUT")
    ROBOT_API_TOKEN: Optional[str] = Field(default=None, env="ROBOT_API_TOKEN")
    ROBOT_API_MOCK_MODE: bool = Field(default=False, env="ROBOT_API_MOCK_MODE")
    
    # CORS设置
    CORS_ORIGINS: List[str] = ["*"]
    CORS_ALLOW_CREDENTIALS: bool = True
    CORS_ALLOW_METHODS: List[str] = ["*"]
    CORS_ALLOW_HEADERS: List[str] = ["*"]
    
    # 日志设置
    LOG_LEVEL: str = "INFO"
    LOG_FILE: str = "logs/app.log"
    LOG_FORMAT: str = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
    
    # 任务调度设置
    TASK_SCHEDULER_WORKER_COUNT: int = 5  # 任务调度器工作线程数量
    
    # 脚本执行配置
    SCRIPT_TIMEOUT: int = os.getenv("SCRIPT_TIMEOUT", 60)  # 脚本执行超时时间（秒）
    SCRIPT_MAX_WORKERS: int = os.getenv("SCRIPT_MAX_WORKERS", 5)  # 脚本执行最大线程数
    
    # 任务导出加密配置
    TASK_EXPORT_ENCRYPTION_KEY: str = Field(default="vwed_task_export_secret_key", env="TASK_EXPORT_ENCRYPTION_KEY") # 导出加密密钥
    TASK_EXPORT_ENCRYPTION_ALGORITHM: str = Field(default="AES", env="TASK_EXPORT_ENCRYPTION_ALGORITHM") # 加密算法
    TASK_EXPORT_IV: str = Field(default="vwed1234task5678", env="TASK_EXPORT_IV") # 初始化向量
    
    # 增强版任务调度器配置
    TASK_SCHEDULER_MIN_WORKER_COUNT: int = 5  # 最小工作线程数
    TASK_SCHEDULER_MAX_WORKER_COUNT: int = 20  # 最大工作线程数
    TASK_SCHEDULER_QUEUE_COUNT: int = 3  # 队列数量
    TASK_SCHEDULER_QUEUE_THRESHOLD_PERCENTILES: List[float] = [0.1, 0.3, 1.0]  # 队列阈值百分比配置
    TASK_SCHEDULER_WORKER_RATIOS: List[float] = [0.6, 0.3, 0.1]  # 工作线程分配比例
    TASK_SCHEDULER_TASK_TIMEOUT: int = 3600  # 任务超时时间（秒）
    TASK_SCHEDULER_MAX_RETRY_COUNT: int = 3  # 最大重试次数
    TASK_SCHEDULER_RETRY_DELAY: int = 60  # 重试基础延迟（秒）
    TASK_SCHEDULER_BACKUP_INTERVAL: int = 300  # 备份间隔（秒）
    TASK_SCHEDULER_BACKUP_DIR: str = os.path.join(DATA_DIR, "task_backups")  # 备份目录
    TASK_SCHEDULER_MAX_BACKUPS: int = 5  # 最大备份数
    TASK_SCHEDULER_ZOMBIE_TASK_CHECK_INTERVAL: int = 60  # 僵尸任务检查间隔（秒）
    TASK_SCHEDULER_CPU_THRESHOLD: float = 80.0  # CPU使用率阈值（百分比）
    TASK_SCHEDULER_MEMORY_THRESHOLD: float = 80.0  # 内存使用率阈值（百分比）
    TASK_SCHEDULER_AUTO_SCALE_INTERVAL: int = 60  # 自动扩缩容间隔（秒）
    TASK_SCHEDULER_WORKER_HEARTBEAT_INTERVAL: int = 30  # 心跳间隔（秒）
    
    @property
    def DATABASE_URL(self) -> str:
        """构建数据库连接URL"""
        if self.DB_DIALECT == 'sqlite':
            return f"sqlite:///{self.DB_NAME}"
        return f"{self.DB_DIALECT}+{self.DB_DRIVER}://{self.DB_USER}:{self.DB_PASSWORD}@{self.DB_HOST}:{self.DB_PORT}/{self.DB_NAME}?charset={self.DB_CHARSET}"
    
    @property
    def DATABASE_ARGS(self) -> Dict[str, Any]:
        """构建数据库连接参数"""
        args = {
            "pool_size": self.DB_POOL_SIZE,
            "max_overflow": self.DB_MAX_OVERFLOW,
            "pool_recycle": self.DB_POOL_RECYCLE,
            "echo": self.DB_ECHO
        }
        
        return args
    
    @property
    def REDIS_URL(self) -> str:
        """构建Redis连接URL"""
        if self.REDIS_PASSWORD:
            return f"redis://:{self.REDIS_PASSWORD}@{self.REDIS_HOST}:{self.REDIS_PORT}/{self.REDIS_DB}"
        return f"redis://{self.REDIS_HOST}:{self.REDIS_PORT}/{self.REDIS_DB}"

    # 更新为Pydantic v2的配置方式
    model_config = {
        "env_file": ".env",
        "env_file_encoding": "utf-8",
        "case_sensitive": True
    }


class DevelopmentConfig(BaseConfig):
    """开发环境配置"""
    DEBUG: bool = True
    DB_ECHO: bool = True  # 开发环境输出SQL语句
    LOG_LEVEL: str = "DEBUG"
    SERVER_RELOAD: bool = True  # 开发环境启用热重载
    STORAGE_API_MOCK_MODE: bool = True  # 开发环境默认使用API模拟模式
    ROBOT_API_MOCK_MODE: bool = True  # 开发环境默认使用机器人API模拟模式


# 根据环境变量选择配置
def get_config():
    """根据环境变量获取配置"""
    return DevelopmentConfig()

# 导出配置
settings = get_config()

# 添加LogConfig类以供logger.py使用
class LogConfig:
    """日志配置类"""
    @staticmethod
    def as_dict():
        """返回日志配置字典"""
        return {
            "level": settings.LOG_LEVEL,
            "file": settings.LOG_FILE,
            "format": settings.LOG_FORMAT
        } 