#!/usr/bin/env python3

import os
import json
import zipfile
import requests
import argparse

# 默认的 API 地址
DEFAULT_URL = "http://122.152.229.91:5005/api/hub/workflow/upload"

def read_metadata(workflow_dir):
    """
    从 metadata.json 中读取 workflow_id 和 version
    """
    metadata_path = os.path.join(workflow_dir, "metadata.json")
    
    if not os.path.exists(metadata_path):
        raise FileNotFoundError(f"在目录中未找到 metadata.json: {metadata_path}")
        
    try:
        with open(metadata_path, 'r', encoding='utf-8') as f:
            data = json.load(f)
            w_id = data.get('id')
            version = data.get('version')
            
            if not w_id or not version:
                raise ValueError("metadata.json 中缺少 'id' 或 'version' 字段")
                
            return w_id, version
    except json.JSONDecodeError:
        raise ValueError(f"metadata.json 格式错误，无法解析")

def zip_directory(source_dir, output_filename):
    """
    将整个目录打包成 zip 文件
    """
    print(f"📦 正在打包目录: {source_dir} -> {output_filename}")
    
    with zipfile.ZipFile(output_filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
        for root, dirs, files in os.walk(source_dir):
            dirs[:] = [d for d in dirs if d != '__pycache__']
            for file in files:
                file_path = os.path.join(root, file)
                arcname = os.path.relpath(file_path, source_dir)
                
                if file == os.path.basename(output_filename):
                    continue
                    
                zipf.write(file_path, arcname)

def upload_workflow(workflow_id, version, zip_path, target_url):
    """
    上传 Zip 文件到指定接口
    """
    print(f"🚀 正在上传到: {target_url}")
    print(f"📄 Info: ID={workflow_id}, Version={version}, File={zip_path}")
    
    params = {
        "workflow_id": workflow_id,
        "version": version
    }
    
    try:
        with open(zip_path, 'rb') as f:
            files = {'file': (os.path.basename(zip_path), f, 'application/zip')}
            response = requests.post(target_url, params=params, files=files)
            
        if response.status_code == 200:
            print("✅ 上传成功！")
            print("服务器响应:", response.json())
        else:
            print(f"❌ 上传失败。状态码: {response.status_code}")
            print("错误信息:", response.text)
            
    except requests.exceptions.RequestException as e:
        print(f"❌ 网络请求错误: {e}")

def main():
    parser = argparse.ArgumentParser(description="自动打包并上传 Workflow")
    
    # 1. 位置参数：工作流目录 (必填)
    parser.add_argument("dir", help="工作流目录的路径")
    
    # 2. 可选参数：URL (选填，不填则使用 default)
    parser.add_argument(
        "--url", 
        default=DEFAULT_URL, 
        help=f"上传接口地址 (默认: {DEFAULT_URL})"
    )
    
    args = parser.parse_args()
    
    workflow_dir = args.dir
    target_url = args.url # 获取解析后的 URL

    temp_zip_name = ''
    
    try:
        # 读取元数据
        w_id, version = read_metadata(workflow_dir)

        temp_zip_name = f"{w_id}_{version}.zip"
        
        # 打包
        zip_directory(workflow_dir, temp_zip_name)
        
        # 上传
        upload_workflow(w_id, version, temp_zip_name, target_url)
        
    except Exception as e:
        print(f"❌ 发生错误: {e}")
    finally:
        if os.path.exists(temp_zip_name):
            os.remove(temp_zip_name)
            print("🧹 已清理临时文件")

if __name__ == "__main__":
    main()