import os
import sys
import shlex
import shutil
import logging
import platform
import subprocess
import tarfile
from tempfile import TemporaryDirectory

logging.basicConfig(
    level=logging.INFO,
    format="[%(asctime)s %(levelname)-7s] %(message)s"
)

PYPI = [
    ("ricequant", "RiceQuant77", "https://pypi.ricequant.com:8080"),
    ("ricequant", "Ricequant123", "https://pypi2.ricequant.com")
]


def _run_command(command):
    logging.debug(command)
    proc = subprocess.run(
        command if platform.system() == "Windows" else shlex.split(command),
        stdout=subprocess.PIPE, stderr=subprocess.STDOUT
    )
    if proc.returncode != 0:
        raise RuntimeError(f"command failed: {command}\n{proc.stdout}")
    else:
        logging.debug(f"\n{proc.stdout}")


def _run_python_command(command):
    _run_command(f"{sys.executable} {command}")


def _pip_install(pkg_name):
    logging.info(f"installing {pkg_name}...")
    _run_python_command(f"-m pip install -i https://pypi.tuna.tsinghua.edu.cn/simple/ {pkg_name}")


def _conda_install(pkg_name):
    logging.info(f"installing {pkg_name} via conda...")
    _run_command(f"conda install -c conda-forge {pkg_name} -y")


def _check_platform_condition(condition):
    """检查平台条件是否满足"""
    if not condition.strip():
        return True
    
    if "sys_platform" in condition:
        current_platform = sys.platform
        if "linux" in condition and current_platform.startswith("linux"):
            return True
        elif "darwin" in condition and current_platform == "darwin":
            return True
        elif "win" in condition and current_platform.startswith("win"):
            return True
        return False
    
    return True


def _parse_and_install_build_requirements(file_path):
    logging.info("=== 安装构建依赖 ===")
    
    with open(file_path, 'r', encoding='utf-8') as f:
        for line in f:
            line = line.strip()
            if not line or line.startswith('#'):
                continue
            
            # 解析格式: package_name[version_spec] ; [platform_condition] ; install_method ; [description]
            parts = line.split(';', 3)
            package_part = parts[0].strip()
            platform_condition = parts[1].strip() if len(parts) > 1 else ""
            install_method = parts[2].strip() if len(parts) > 2 else "pip"
            description = parts[3].strip() if len(parts) > 3 else ""
            
            # 检查平台条件
            if not _check_platform_condition(platform_condition):
                logging.debug(f"跳过 {package_part} (平台条件不匹配: {platform_condition})")
                continue
            if install_method.lower() == "conda":
                # 对于 conda 安装，只使用包名（不包含版本规范）
                package_name = package_part
                for op in ['>=', '<=', '==', '!=', '~=', '>', '<']:
                    if op in package_part:
                        package_name = package_part.split(op)[0].strip()
                        break
                _conda_install(package_name)
            elif install_method.lower() == "pip":
                _pip_install(package_part)
            else:
                logging.warning(f"未知的安装方法 '{install_method}' for {package_part}")
                continue
                    
            logging.info(f"✓ {package_part} 安装成功 ({install_method})")
    
    logging.info("=== 构建依赖安装完成 ===")


def build(requirements_txt: str):
    # 安装构建依赖
    build_req_file = os.path.join(os.path.dirname(__file__), "build_requirements.txt")
    _parse_and_install_build_requirements(build_req_file)
    
    if platform.system() == "Linux":
        _pip_install("auditwheel")
    elif platform.system() == "Darwin":
        _pip_install("delocate")
    _pip_install("twine")

    pkg_dir_obj, source_dir_obj, whl_dir_obj = TemporaryDirectory(), TemporaryDirectory(), TemporaryDirectory()
    pkg_dir, source_dir, whl_dir = pkg_dir_obj.name, source_dir_obj.name, whl_dir_obj.name
    try:
        logging.info("downloading pkgs...")
        _run_python_command(f"-m pip download -i https://pypi.tuna.tsinghua.edu.cn/simple/ --extra-index-url https://rquser:Ricequant8@pypi2.ricequant.com/simple/ --progress-bar off -r {requirements_txt} -d {pkg_dir} --no-deps")
        for file in os.listdir(pkg_dir):
            if file.endswith(".whl"):
                logging.info(f"copying {file}...")
                shutil.copy(os.path.join(pkg_dir, file), whl_dir)
                continue
            if not file.endswith(".tar.gz"):
                raise NotImplementedError(f"unsupported file format: {file}")
            logging.info(f"decompressing {file}...")
            with tarfile.open(os.path.join(pkg_dir, file)) as f:
                f.extractall(source_dir)
        for dir in os.listdir(source_dir):
            logging.info(f"building {dir}...")
            os.chdir(os.path.join(source_dir, dir))

            # 检查使用哪种构建方式
            if os.path.exists("setup.py"):
                _run_python_command(f"setup.py bdist_wheel")
            elif os.path.exists("pyproject.toml"):
                # 使用 pip wheel 构建（支持 PEP 517）
                _run_python_command(f"-m pip wheel . --no-deps -w dist")
            else:
                raise RuntimeError(f"No setup.py or pyproject.toml found in {dir}")

            for whl_file in os.listdir("dist"):
                whl_file = os.path.join("dist", whl_file)
                if platform.system() == "Darwin":
                    _run_command(f"delocate-wheel -w {whl_dir} {whl_file}")
                elif platform.system() == "Linux":
                    # 根据Python版本选择合适的manylinux标签
                    if sys.version_info[:2] >= (3, 12):
                        _run_command(f"auditwheel repair -w {whl_dir} {whl_file}")  # 使用auto检测
                    else:
                        _run_command(f"auditwheel repair -w {whl_dir} {whl_file} --plat manylinux_2_17_x86_64")
                else:
                    shutil.copy(whl_file, whl_dir)

        for file in os.listdir(whl_dir):
            for username, password, url in PYPI:
                logging.info(f"uploading {file} to {url}...")
                # 在 Windows 下添加 --disable-progress-bar 避免编码问题
                progress_bar_flag = "--disable-progress-bar" if platform.system() == "Windows" else ""
                try:
                    # 移除 --skip-existing 参数，因为某些私有 PyPI 服务器不支持
                    _run_command("python -m twine upload --repository-url {} -u {} -p {} {} {}".format(
                        url, username, password, progress_bar_flag, os.path.join(whl_dir, file)
                    ))
                    logging.info(f"✓ {file} uploaded to {url}")
                except RuntimeError as e:
                    # 如果上传失败（可能是文件已存在），记录警告但继续
                    if "already exists" in str(e).lower() or "file already exists" in str(e).lower():
                        logging.warning(f"⚠ {file} already exists on {url}, skipping...")
                    else:
                        logging.error(f"✗ Failed to upload {file} to {url}: {e}")
                        raise
    finally:
        for dir in [pkg_dir_obj, source_dir_obj, whl_dir_obj]:
            try:
                dir.cleanup()
            except:
                continue


if __name__ == "__main__":
    build(os.path.join(os.path.dirname(__file__), "requirements.txt"))
