# -*- coding: utf-8 -*-
"""
deploy_service_manage.py — 部署服务管理模块到 5.60 Docker 容器

部署步骤：
  1. 上传后端 Python 文件到 /data/third_party/monitor-platform/
  2. docker cp 到 troubleshoot 容器
  3. 上传前端 dist 到 /data/third_party/monitor-platform/frontend/dist/
  4. 同步到 /opt/troubleshoot/dist/
  5. 重启容器
  6. 验证 health
"""

import paramiko
import os
import time
from pathlib import Path

HOST = '192.168.5.60'
USER = 'ubains'
PASSWORD = 'Ubains@123'
REPO = 'E:/GithubData/ubains-module-test/troubleshoot-ai-assistant'
REMOTE_BASE = '/data/third_party/monitor-platform'
CONTAINER = 'troubleshoot'

# 需要部署的后端文件（相对仓库根目录）
BACKEND_FILES = [
    # 核心：服务管理模块（新功能）
    'skill/code/web/services/service_manage.py',
    'skill/code/web/routes/service_manage.py',
    'skill/code/web/utils/paths.py',
    # 其他有变更的文件
    'skill/code/web/services/product_service.py',
    'skill/code/web/routes/troubleshoot.py',
    'skill/code/web/routes/version.py',
    'skill/code/web/services/ai_service.py',
    'skill/code/web/cache_manager.py',
    'skill/code/web/users.json',
    'skill/code/web/products.json',
]

def main():
    s = paramiko.SSHClient()
    s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    s.connect(HOST, username=USER, password=PASSWORD)
    sf = s.open_sftp()

    print("=" * 60)
    print("  Deploy Service Management Module")
    print("=" * 60)

    # ============================================================
    # Step 1: 上传后端文件
    # ============================================================
    print("\n[1/4] Uploading backend files...")
    for f in BACKEND_FILES:
        local = os.path.join(REPO, f.replace('/', os.sep))
        remote = f'{REMOTE_BASE}/{f}'
        # 确保远程目录存在
        rdir = os.path.dirname(remote)
        s.exec_command(f'mkdir -p "{rdir}"')
        # 上传
        sf.put(local, remote)
        print(f"  [OK] {f}")

    # ============================================================
    # Step 2: docker cp 到容器（挂载卷文件除外）
    # ============================================================
    print("\n[2/4] Copying to container...")
    # users.json 是挂载卷（/opt/troubleshoot/data/users.json -> /app/web/users.json）
    # 不能 docker cp，需直接更新宿主机挂载文件
    MOUNTED_FILES = {'skill/code/web/users.json'}
    for f in BACKEND_FILES:
        if f in MOUNTED_FILES:
            local = os.path.join(REPO, f.replace('/', os.sep))
            mount_target = '/opt/troubleshoot/data/users.json'
            sf.put(local, mount_target)
            print(f"  [OK] {f} -> host mount {mount_target}")
            continue
        remote = f'{REMOTE_BASE}/{f}'
        container_path = f'/app/web/{f.replace("skill/code/web/", "")}'
        stdin, stdout, stderr = s.exec_command(
            f'sudo docker cp "{remote}" "{CONTAINER}:{container_path}"'
        )
        err = stderr.read().decode().strip()
        if err:
            print(f"  [FAIL] {f}: {err}")
        else:
            print(f"  [OK] {container_path}")

    # ============================================================
    # Step 3: 上传前端 dist
    # ============================================================
    print("\n[3/4] Uploading frontend dist...")
    local_dist = os.path.join(REPO, 'frontend', 'dist')
    for root, dirs, files in os.walk(local_dist):
        for fn in files:
            lpath = os.path.join(root, fn)
            rel = os.path.relpath(lpath, local_dist)
            rpath = f'{REMOTE_BASE}/frontend/dist/{rel.replace(chr(92), "/")}'
            rdir = os.path.dirname(rpath)
            s.exec_command(f'mkdir -p "{rdir}"')
            sf.put(lpath, rpath)

    # 同步到宿主机挂载目录
    s.exec_command('sudo rm -rf /opt/troubleshoot/dist/*')
    s.exec_command('sudo cp -r /data/third_party/monitor-platform/frontend/dist/* /opt/troubleshoot/dist/')
    print("  [OK] Frontend dist deployed to /opt/troubleshoot/dist/")

    # ============================================================
    # Step 4: 重启容器
    # ============================================================
    print("\n[4/4] Restarting container...")
    stdin, stdout, stderr = s.exec_command('sudo docker restart troubleshoot')
    out = stdout.read().decode().strip()
    err = stderr.read().decode().strip()
    print(f"  {'[OK]' if 'troubleshoot' in out else '[FAIL]'} {out or err}")

    # 等待启动
    print("\nWaiting for service...")
    time.sleep(8)

    # 验证
    print("\nVerifying...")
    stdin, stdout, stderr = s.exec_command(
        'curl -s http://localhost/api/health | python3 -m json.tool 2>/dev/null || curl -s http://localhost/api/health'
    )
    result = stdout.read().decode().strip()
    if result:
        print(f"  Health check response:\n{result[:500]}")
        if 'ok' in result.lower() or 'success' in result.lower():
            print("\n[OK] Deployment verified successfully!")
        else:
            print("\n[WARN] Service may not be fully ready yet")
    else:
        err_text = stderr.read().decode().strip()
        print(f"  [FAIL] {err_text}")

    # 验证容器内文件
    print("\nVerifying container files...")
    stdin, stdout, stderr = s.exec_command(
        'sudo docker exec troubleshoot ls -la /app/web/services/service_manage.py /app/web/routes/service_manage.py 2>&1'
    )
    print(stdout.read().decode().strip())

    sf.close()
    s.close()
    print("\n" + "=" * 60)
    print("  Deployment Complete!")
    print("=" * 60)


if __name__ == '__main__':
    main()