"""
MariaDB 连接管理。

使用 SQLAlchemy 连接池，通过 SSH 隧道访问远程数据库。
连接失败时自动尝试重建 SSH 隧道并重连。
"""

import os
import subprocess
import time

from sqlalchemy import create_engine, text
from sqlalchemy.orm import sessionmaker

from config.settings import MARIADB_CONFIG

_engine = None
_SessionLocal = None


def _build_url() -> str:
    cfg = MARIADB_CONFIG
    return (
        "mysql+pymysql://{}:{}"
        "@{}:{}/{}"
        "?charset={}"
    ).format(cfg["user"], cfg["password"], cfg["host"], cfg["port"], cfg["database"], cfg["charset"])


def _reconnect_ssh() -> bool:
    """自动运行 autossh.sh 重建 SSH 隧道。每次调用都会尝试。"""

    candidates = [
        os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(
            os.path.abspath(__file__)))), "shared", "script", "autossh.sh"),
        os.path.expanduser("~/Downloads/cc-cursor/shared/script/autossh.sh"),
    ]
    script = None
    for c in candidates:
        if os.path.exists(c):
            script = c
            break

    if script is None:
        print("[DB] SSH 脚本未找到")
        return False

    try:
        print("[DB] 尝试重建 SSH 隧道: {}".format(script))
        result = subprocess.run(["bash", script], capture_output=True, text=True, timeout=15)
        time.sleep(3)  # 等待隧道建立
        if result.returncode == 0:
            print("[DB] SSH 隧道重建完成")
            return True
        else:
            print("[DB] SSH 隧道重建失败: {}".format(result.stderr[:200]))
            return False
    except Exception as e:
        print("[DB] SSH 执行异常: {}".format(e))
        return False


def _test_engine(engine) -> bool:
    """测试引擎连接是否存活。"""
    try:
        with engine.connect() as conn:
            conn.execute(text("SELECT 1"))
        return True
    except Exception:
        return False


def get_engine():
    """获取 SQLAlchemy Engine（懒初始化，断连时自动重连）。"""
    global _engine, _SessionLocal

    # 已有引擎但连接断开 → dispose 旧池 → SSH 重连 → 重建引擎
    if _engine is not None and not _test_engine(_engine):
        print("[DB] 连接已断开，尝试自动恢复...")
        _engine.dispose()  # 杀死所有旧连接
        _engine = None
        if _reconnect_ssh():
            print("[DB] 连接已恢复")
        else:
            print("[DB] 自动恢复失败，将无法连接数据库")

    # 创建引擎（首次或重建后）
    if _engine is None:
        cfg = MARIADB_CONFIG
        _engine = create_engine(
            _build_url(),
            pool_size=cfg["pool_size"],
            pool_recycle=cfg["pool_recycle"],
            pool_pre_ping=True,   # 每次取连接前先 SELECT 1 验证存活
            echo=False,
        )
        # Session factory 下次获取时自动绑定新引擎
        _SessionLocal = None

    return _engine


def get_session():
    """获取一个新的数据库会话。"""
    global _SessionLocal
    if _SessionLocal is None:
        _SessionLocal = sessionmaker(bind=get_engine())
    return _SessionLocal()


def test_connection() -> bool:
    """测试数据库连接是否正常。"""
    try:
        engine = get_engine()
        return _test_engine(engine)
    except Exception as e:
        print("[ERROR] 数据库连接失败: {}".format(e))
        return False
