import os
import sys
import subprocess
import logging
import requests
import zipfile
import tarfile
from pathlib import Path
from .config import Config

config = Config()

def get_logger(name):
    logger = logging.getLogger(name)
    logger.setLevel(config.get('log_level'))
    
    if not logger.handlers:
        ch = logging.StreamHandler()
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        ch.setFormatter(formatter)
        logger.addHandler(ch)
    
    return logger

logger = get_logger(__name__)

def run_command(cmd, admin=False):
    """运行系统命令"""
    try:
        if admin and sys.platform == 'win32':
            cmd = f"powershell Start-Process -Verb RunAs -Wait -FilePath '{cmd[0]}' -ArgumentList '{' '.join(cmd[1:])}'"
            process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        else:
            process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        
        stdout, stderr = process.communicate()
        return process.returncode, stdout.decode('utf-8', 'ignore'), stderr.decode('utf-8', 'ignore')
    except Exception as e:
        logger.error(f"Command execution failed: {e}")
        return -1, "", str(e)

def download_file(url, dest_path):
    """下载文件"""
    try:
        response = requests.get(url, stream=True)
        response.raise_for_status()
        
        with open(dest_path, 'wb') as f:
            for chunk in response.iter_content(chunk_size=8192):
                f.write(chunk)
        return True
    except Exception as e:
        logger.error(f"Download failed: {e}")
        return False

def extract_archive(file_path, extract_dir):
    """解压文件"""
    try:
        if file_path.endswith('.zip'):
            with zipfile.ZipFile(file_path, 'r') as zip_ref:
                zip_ref.extractall(extract_dir)
        elif file_path.endswith('.tar.gz') or file_path.endswith('.tgz'):
            with tarfile.open(file_path, 'r:gz') as tar_ref:
                tar_ref.extractall(extract_dir)
        return True
    except Exception as e:
        logger.error(f"Extraction failed: {e}")
        return False

def get_binary_dir():
    """获取二进制文件目录"""
    module_dir = Path(__file__).parent.parent
    bin_dir = module_dir / 'bin' / config.system_platform / config.architecture
    bin_dir.mkdir(parents=True, exist_ok=True)
    return bin_dir

def get_vlmcsd_path():
    """获取vlmcsd路径"""
    config_path = config.get('vlmcsd_path')
    if config_path and os.path.exists(config_path):
        return config_path
    
    bin_dir = get_binary_dir()
    
    # 尝试查找已存在的二进制文件
    binary_name = "vlmcsd.exe" if sys.platform == "win32" else "vlmcsd"
    binary_path = bin_dir / binary_name
    
    if binary_path.exists():
        return str(binary_path)
    
    # 如果没有找到，尝试下载
    if not download_vlmcsd():
        return None
    
    return str(binary_path)

def download_vlmcsd():
    """下载vlmcsd二进制文件"""
    logger.info("Downloading vlmcsd binary...")
    
    base_url = "https://github.com/Wind4/vlmcsd/releases/download/svn1113/binaries.tar.gz"
    temp_dir = Path.home() / ".kms_activator" / "temp"
    temp_dir.mkdir(parents=True, exist_ok=True)
    
    archive_path = temp_dir / "binaries.tar.gz"
    
    if not download_file(base_url, archive_path):
        return False
    
    if not extract_archive(archive_path, temp_dir):
        return False
    
    # 找到对应的二进制文件
    bin_dir = get_binary_dir()
    platform_name = config.system_platform
    arch_name = config.architecture
    
    # 在解压目录中查找对应平台的二进制文件
    source_dir = temp_dir / "binaries" / platform_name.capitalize()
    if not source_dir.exists():
        logger.error(f"Unsupported platform: {platform_name}")
        return False
    
    # 根据架构选择文件
    if platform_name == "windows":
        binary_name = f"vlmcsd-{arch_name}.exe"
    else:
        binary_name = f"vlmcsd-{arch_name}-musl-static"
    
    source_path = None
    for root, _, files in os.walk(source_dir):
        for file in files:
            if file == binary_name:
                source_path = Path(root) / file
                break
    
    if not source_path:
        logger.error(f"Binary not found: {binary_name}")
        return False
    
    # 复制到目标目录
    target_path = bin_dir / ("vlmcsd.exe" if platform_name == "windows" else "vlmcsd")
    source_path.rename(target_path)
    
    # 设置可执行权限
    if platform_name != "windows":
        os.chmod(target_path, 0o755)
    
    # 更新配置
    config.set('vlmcsd_path', str(target_path))
    
    logger.info(f"vlmcsd downloaded to {target_path}")
    return True