from sqlite_vfs.folder_packer import FolderPacker
from sqlite_vfs.core import SQLiteVFS
import json
from module_bank import PythonToSQLite
import os
import shutil
from pathlib import Path
import traceback
import sys


def main(vfs_path: str = "application.svfs", mbank_path: str = "plugins.mbank"):
    """
    构建应用程序资源包和虚拟文件系统
    
    Args:
        vfs_path: 输出的VFS文件路径
        mbank_path: 输出的模块库文件路径
    """
    build_dir = r"build"
    
    try:
        # 清理旧的构建目录
        if os.path.exists(build_dir):
            print(f"清理旧的构建目录: {build_dir}")
            shutil.rmtree(build_dir, ignore_errors=True)
        
        # 创建构建目录
        build_dir_path = Path(build_dir)
        if not build_dir_path.exists():
            build_dir_path.mkdir(parents=True, exist_ok=True)
        
        print("开始构建...")
        
        # 读取配置文件
        try:
            with open("config.json", 'r') as file:
                config_data = json.load(file)
                model_map = config_data["model_map"]
            print("配置文件加载成功")
        except FileNotFoundError:
            print("错误: 找不到配置文件 config.json")
            return
        except json.JSONDecodeError as e:
            print(f"错误: 配置文件格式错误 - {e}")
            return
        except KeyError:
            print("错误: 配置文件中缺少 'model_map' 字段")
            return
        
        # 初始化VFS
        try:
            vfs = SQLiteVFS(vfs_path)
            folder_packer = FolderPacker(vfs)
            print(f"VFS初始化成功: {vfs_path}")
        except Exception as e:
            print(f"错误: 初始化VFS失败 - {e}")
            return
        
        # 初始化Python模块打包器
        try:
            packer = PythonToSQLite(mbank_path)
            print(f"模块打包器初始化成功: {mbank_path}")
        except Exception as e:
            print(f"错误: 初始化模块打包器失败 - {e}")
            return
        
        # 添加配置文件到VFS
        try:
            folder_packer.add_file("config.json", "config.json")
            print("配置文件已添加到VFS")
        except Exception as e:
            print(f"错误: 添加配置文件到VFS失败 - {e}")
            return
        
        # 处理每个模型配置
        processed_models = 0
        for model_name, model_value in model_map.items():
            try:
                config_file_path = model_value["config"]
                module: str = model_value["module"]
                
                # 打包Python模块
                print(f"打包模块: {module}")
                packer.pack_directory(module.split(".")[0])
                
                # 添加模型配置文件到VFS
                folder_packer.add_file(config_file_path, config_file_path)
                
                # 读取模型配置文件获取bmodel路径
                with open(config_file_path, "r") as file:
                    model_config = json.load(file)
                    bmodel_path = model_config["bmodel_path"]
                
                # 添加bmodel文件到VFS
                if os.path.exists(bmodel_path):
                    folder_packer.add_file(bmodel_path, bmodel_path)
                    print(f"  添加模型文件: {bmodel_path}")
                else:
                    print(f"  警告: 模型文件不存在 {bmodel_path}")
                
                processed_models += 1
                
            except KeyError as e:
                print(f"错误: 模型 '{model_name}' 配置缺少必要字段 - {e}")
                continue
            except FileNotFoundError as e:
                print(f"错误: 找不到模型 '{model_name}' 的文件 - {e}")
                continue
            except json.JSONDecodeError as e:
                print(f"错误: 模型 '{model_name}' 的配置文件格式错误 - {e}")
                continue
            except Exception as e:
                print(f"错误: 处理模型 '{model_name}' 时发生未知错误 - {e}")
                continue
        
        if processed_models == 0:
            print("警告: 没有成功处理任何模型")
        
        # 显示VFS内容
        print("\nVFS内容:")
        try:
            items = vfs.list_directory("/")
            for item in items:
                file_type = "DIR" if item["is_directory"] else "FILE"
                size_info = f" ({item['file_size']} bytes)" if not item["is_directory"] else ""
                print(f"  {file_type}: {item['path']}{size_info}")
        except Exception as e:
            print(f"警告: 无法列出VFS内容 - {e}")
        
        # 复制文件到构建目录
        try:
            print("\n复制文件到构建目录...")
            
            # 复制主程序
            main_py_source = "public/main.py"
            if os.path.exists(main_py_source):
                shutil.copy(main_py_source, build_dir)
                print(f"  复制: {main_py_source}")
            else:
                print(f"  警告: 主程序文件不存在 {main_py_source}")
            
            # 复制VFS文件
            if os.path.exists(vfs_path):
                shutil.copy(vfs_path, build_dir)
                print(f"  复制: {vfs_path}")
            else:
                print(f"  警告: VFS文件不存在 {vfs_path}")
            
            # 复制模块库文件
            if os.path.exists(mbank_path):
                shutil.copy(mbank_path, build_dir)
                print(f"  复制: {mbank_path}")
            else:
                print(f"  警告: 模块库文件不存在 {mbank_path}")
            
        except Exception as e:
            print(f"错误: 复制文件失败 - {e}")
            return
        
        print(f"\n构建成功完成! 输出目录: {build_dir}")
        print(f"  主程序: {os.path.join(build_dir, 'main.py')}")
        print(f"  VFS文件: {os.path.join(build_dir, os.path.basename(vfs_path))}")
        print(f"  模块库: {os.path.join(build_dir, os.path.basename(mbank_path))}")
        
    except Exception as e:
        print(f"\n构建过程中发生严重错误: {e}")
        print("错误详情:")
        traceback.print_exc()
        
        # 清理不完整的构建目录
        if os.path.exists(build_dir):
            print(f"\n清理不完整的构建目录: {build_dir}")
            try:
                shutil.rmtree(build_dir, ignore_errors=True)
            except Exception as cleanup_error:
                print(f"警告: 清理构建目录失败 - {cleanup_error}")
        
        sys.exit(1)


if __name__ == "__main__":
    main()