#!/usr/bin/env python3
"""
publish_template.py

发布模板文件夹到七牛 CDN，完成后重建并上传 template-index.json。

CDN 路径：{CDN_PREFIX}/{folder_name}/{version}/{filename}
版本号从 templates/{folder}/v{N}/ 子目录读取（以本地最新版本为准）。

用法：
    python3 scripts/publish_template.py <模板文件夹路径>
    python3 scripts/publish_template.py --all
"""
import argparse
import re
import subprocess
import sys
from pathlib import Path

from qiniu import Auth, put_file_v2, CdnManager

QINIU_KEY    = "T3tgxM7EMx1j4VESw4m4PIfFXoOvBo-wQEOQewXX"
QINIU_SECRET = "PVZvlKVOjX2RqlV2ILMg-QwpNMssOlpVbaEzypz0"
QINIU_BUCKET = "yiran1"
CDN_DOMAIN   = "https://cdn.yiranlaoshi.com"
CDN_INDEX_KEY = "myclaw/live/yiran/skills/yiran-playground-template-use/template-index.json"
CDN_PREFIX    = "myclaw/live/yiran/skills/yiran-playground-template-use/templates"

q           = Auth(QINIU_KEY, QINIU_SECRET)
cdn_manager = CdnManager(q)


def get_latest_version_dir(folder: Path):
    """返回最新 v{N} 子目录和版本号，没有则返回 (None, 0)"""
    max_v = 0
    result = None
    for d in folder.iterdir():
        if d.is_dir():
            m = re.match(r'^v(\d+)$', d.name)
            if m:
                v = int(m.group(1))
                if v > max_v:
                    max_v = v
                    result = d
    return result, max_v


def upload_file(local_path: Path, cdn_key: str) -> str:
    token = q.upload_token(QINIU_BUCKET, cdn_key, 3600, policy={'insertOnly': 0})
    ret, info = put_file_v2(token, cdn_key, str(local_path))
    if info.status_code != 200:
        raise RuntimeError('上传失败 {}: {}'.format(local_path.name, info))
    cdn_url = '{}/{}'.format(CDN_DOMAIN, cdn_key)
    cdn_manager.refresh_urls([cdn_url])
    return cdn_url


def publish(folder_path: Path):
    folder_name = folder_path.name
    version_dir, version_num = get_latest_version_dir(folder_path)

    if not version_dir:
        print('⚠️  {} 没有版本子目录，跳过'.format(folder_name))
        return

    version_str = 'v{}'.format(version_num)
    files = [f for f in version_dir.rglob('*') if f.is_file() and f.name != '.sync-done']

    if not files:
        print('⚠️  文件夹为空: {}/{}'.format(folder_name, version_str))
        return

    print('📂 发布: {}/{}'.format(folder_name, version_str))
    for f in sorted(files):
        rel = f.relative_to(version_dir)
        cdn_key = '{}/{}/{}/{}'.format(CDN_PREFIX, folder_name, version_str, rel.as_posix())
        cdn_url = upload_file(f, cdn_key)
        print('  ⬆️  {} → {}'.format(rel, cdn_url))

    print('✅ 完成: {}/{}\n'.format(folder_name, version_str))


def publish_index(pipeline_root: Path):
    index_script = pipeline_root / 'scripts' / 'build_template_index.py'
    print('🔄 重建 template-index.json ...')
    subprocess.run(['python3', str(index_script)], check=True)

    index_file = pipeline_root / 'template-index.json'
    if not index_file.is_file():
        print('⚠️  template-index.json 未生成，跳过上传')
        return

    token = q.upload_token(QINIU_BUCKET, CDN_INDEX_KEY, 3600, policy={'insertOnly': 0})
    ret, info = put_file_v2(token, CDN_INDEX_KEY, str(index_file))
    if info.status_code != 200:
        raise RuntimeError('index 上传失败: {}'.format(info))
    cdn_url = '{}/{}'.format(CDN_DOMAIN, CDN_INDEX_KEY)
    cdn_manager.refresh_urls([cdn_url])
    print('  ⬆️  已上传索引 → {}'.format(cdn_url))


def main():
    parser = argparse.ArgumentParser(description='发布模板到七牛 CDN')
    group = parser.add_mutually_exclusive_group(required=True)
    group.add_argument('folder', nargs='?', help='单个模板文件夹路径')
    group.add_argument('--all', action='store_true', help='发布 templates/ 下所有模板')
    args = parser.parse_args()

    pipeline_root = Path(__file__).resolve().parent.parent

    if args.all:
        templates_dir = pipeline_root / 'templates'
        folders = sorted(d for d in templates_dir.iterdir() if d.is_dir())
        if not folders:
            print('⚠️  templates/ 下没有找到任何模板文件夹')
            sys.exit(0)
        print('📦 共 {} 个模板，开始全量发布...\n'.format(len(folders)))
        for folder in folders:
            publish(folder)
    else:
        folder = Path(args.folder).expanduser().resolve()
        if not folder.is_dir():
            print('❌ 路径不存在或不是文件夹: {}'.format(folder))
            sys.exit(1)
        publish(folder)

    publish_index(pipeline_root)


if __name__ == '__main__':
    main()
