# -*- coding: utf-8 -*-
"""
upload_to_server.py - 上传更新的文件到 192.168.5.60 服务器
"""

import paramiko
import os
import time
from datetime import datetime

# 从环境变量读取配置
HOST = os.environ.get('SSH_HOST', '192.168.5.60')
USER = os.environ.get('SSH_USER', 'ubains')
PASSWORD = os.environ.get('SSH_PASSWORD', '')
REMOTE_BASE = '/opt/troubleshoot'

if not PASSWORD:
    print("错误：SSH_PASSWORD 环境变量未设置")
    print("请设置环境变量或创建 .env 文件")
    exit(1)

# 本地部署目录
# P0-3 后统一数据源在 skill/code/web/，deploy/web/ 已删除
LOCAL_BASE = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "skill", "code", "web"))

# 仓库根目录（用于 deploy/ 下的向量文件等）
REPO_ROOT = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))

# 远程 web 目录（与 deploy.sh 的 DEPLOY_DIR/web 对应）
REMOTE_WEB_DIR = REMOTE_BASE + "/web"

# 需要上传的单个文件（相对 LOCAL_BASE）
FILES_TO_UPLOAD = [
    ('server.py', 'web/server.py'),
    ('cache_manager.py', 'web/cache_manager.py'),
    ('decorators.py', 'web/decorators.py'),  # P1-3：url_for('login')→url_for('auth.login')
    ('container.py', 'web/container.py'),    # P1-3：依赖容器
    ('search_engine.py', 'web/search_engine.py'),  # P2-1：向量搜索 + TF-IDF 降级
]

# 需要上传的部署文件（相对仓库根目录，非 LOCAL_BASE）
# P2-1：向量索引文件随索引一起部署到 REMOTE_BASE
DEPLOY_FILES_TO_UPLOAD = [
    ('搜索向量.json', ''),  # 远程路径在 REMOTE_BASE 下
]

# 需要上传的目录（相对 LOCAL_BASE → 远程 web 目录下同名子目录）
# P1-1 新增 utils/ 模块；P1-3 新增 routes/ services/ 目录；P1 收尾新增 templates
DIRS_TO_UPLOAD = [
    ('utils', 'web/utils'),
    ('routes', 'web/routes'),        # P1-3：5 个 Blueprint
    ('services', 'web/services'),    # P1-3：ai_service / record_service
    ('templates', 'web/templates'),  # P1 收尾：errMsg 前端兼容适配
]

def upload_files():
    print("="*60)
    print("  Troubleshoot - Upload Files")
    print("="*60)
    print("Server: " + HOST)
    print("User: " + USER)
    print("Remote: " + REMOTE_BASE)
    print("="*60)

    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())

    try:
        print("\n[1/4] Connecting...")
        ssh.connect(HOST, username=USER, password=PASSWORD)
        print("[OK] Connected")

        print("\n[2/4] Backing up...")
        today = datetime.now().strftime('%Y%m%d')

        print("\n[3/4] Uploading files...")
        sftp = ssh.open_sftp()

        # 确保远程 web 目录存在
        ssh.exec_command(f'mkdir -p {REMOTE_WEB_DIR}')[1].channel.recv_exit_status()
        # 确保远程 utils 目录存在
        ssh.exec_command(f'mkdir -p {REMOTE_BASE}/web/utils')[1].channel.recv_exit_status()

        # 上传单个文件
        for local_rel, remote_rel in FILES_TO_UPLOAD:
            local_path = os.path.join(LOCAL_BASE, local_rel)
            remote_path = REMOTE_BASE + "/" + remote_rel

            if os.path.exists(local_path):
                print("  Uploading: " + local_rel)
                sftp.put(local_path, remote_path)
                print("  [OK] " + remote_path)
            else:
                print("  [FAIL] File not found: " + local_path)

        # 上传部署文件（向量索引等，在 deploy/ 目录下）
        for local_rel, remote_subdir in DEPLOY_FILES_TO_UPLOAD:
            local_path = os.path.join(REPO_ROOT, "deploy", local_rel)
            remote_path = REMOTE_BASE + "/" + remote_subdir + ("/" if remote_subdir else "") + local_rel

            if os.path.exists(local_path):
                print("  Uploading deploy file: " + local_rel)
                sftp.put(local_path, remote_path)
                print("  [OK] " + remote_path)
            else:
                print("  [SKIP] Deploy file not found: " + local_path + " (will use TF-IDF fallback)")

        # 上传目录（递归）
        for local_rel, remote_rel in DIRS_TO_UPLOAD:
            local_dir = os.path.join(LOCAL_BASE, local_rel)
            remote_dir = REMOTE_BASE + "/" + remote_rel
            ssh.exec_command(f'mkdir -p {remote_dir}')[1].channel.recv_exit_status()

            if not os.path.isdir(local_dir):
                print("  [FAIL] Dir not found: " + local_dir)
                continue

            print("  Uploading dir: " + local_rel + "/")
            for fname in os.listdir(local_dir):
                lpath = os.path.join(local_dir, fname)
                if os.path.isfile(lpath) and not fname.endswith('.pyc'):
                    rpath = remote_dir + "/" + fname
                    sftp.put(lpath, rpath)
                    print("    [OK] " + remote_rel + "/" + fname)

        sftp.close()
        print("\n[OK] Files uploaded")

        print("\n[4/4] Restarting service...")
        restart_cmd = (
            'cd /opt/troubleshoot/web && '
            'pkill -f "python.*server.py" || true && '
            'sleep 2 && '
            'nohup python3 server.py > /tmp/troubleshoot.log 2>&1 &'
        )
        stdin, stdout, stderr = ssh.exec_command(restart_cmd)
        stdout.read()
        print("[OK] Service restarted")

        print("\nWaiting for service...")
        time.sleep(3)

        print("\n[5/5] Verifying...")
        stdin, stdout, stderr = ssh.exec_command('curl -s http://localhost:8088/api/health')
        result = stdout.read().decode()

        if result and 'ok' in result:
            print("[OK] Service is running")
            print("\nHealth check response:")
            print(result[:300])
        else:
            print("[FAIL] Service may not be running")
            stdin, stdout, stderr = ssh.exec_command('tail -20 /tmp/troubleshoot.log')
            print(stderr.read().decode())

        print("\n" + "="*60)
        print("  Deployment Complete!")
        print("="*60)
        print("URL: http://" + HOST + ":8088")
        print("Health: http://" + HOST + ":8088/api/health")
        print("="*60)

    except Exception as e:
        print("\n[ERROR] " + str(e))
        import traceback
        traceback.print_exc()

    finally:
        ssh.close()


if __name__ == '__main__':
    upload_files()
