"""创建脚本引擎相关表

Revision ID: 003
Revises: 002
Create Date: 2025-01-11 12:00:00.000000

"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.dialects import mysql

# revision identifiers, used by Alembic.
revision = '003'
down_revision = '002'
branch_labels = None
depends_on = None


def upgrade():
    """创建脚本引擎相关表"""
    
    # 创建脚本项目表
    op.create_table('vwed_script_project',
        sa.Column('id', sa.Integer(), nullable=False, comment='项目ID'),
        sa.Column('project_name', sa.String(100), nullable=False, comment='项目名称'),
        sa.Column('project_path', sa.String(500), nullable=False, comment='项目路径'),
        sa.Column('description', sa.Text(), nullable=True, comment='项目描述'),
        sa.Column('status', sa.String(20), nullable=False, server_default='active', comment='项目状态'),
        sa.Column('created_by', sa.String(100), nullable=True, comment='创建者'),
        sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='创建时间'),
        sa.Column('updated_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW() ON UPDATE NOW()'), comment='更新时间'),
        sa.PrimaryKeyConstraint('id'),
        sa.UniqueConstraint('project_path'),
        comment='脚本项目表'
    )
    
    # 创建脚本文件表
    op.create_table('vwed_script_file',
        sa.Column('id', sa.Integer(), nullable=False, comment='文件ID'),
        sa.Column('project_id', sa.Integer(), nullable=False, comment='所属项目ID'),
        sa.Column('file_name', sa.String(255), nullable=False, comment='文件名'),
        sa.Column('file_path', sa.String(500), nullable=False, comment='文件相对路径'),
        sa.Column('file_type', sa.String(20), nullable=False, server_default='python', comment='文件类型'),
        sa.Column('content', sa.Text(), nullable=True, comment='文件内容'),
        sa.Column('size', sa.Integer(), nullable=True, server_default='0', comment='文件大小'),
        sa.Column('encoding', sa.String(20), nullable=True, server_default='utf-8', comment='文件编码'),
        sa.Column('is_directory', sa.Boolean(), nullable=True, server_default='0', comment='是否为目录'),
        sa.Column('is_executable', sa.Boolean(), nullable=True, server_default='0', comment='是否可执行'),
        sa.Column('has_boot_function', sa.Boolean(), nullable=True, server_default='0', comment='是否包含boot函数'),
        sa.Column('status', sa.String(20), nullable=False, server_default='active', comment='文件状态'),
        sa.Column('created_by', sa.String(100), nullable=True, comment='创建者'),
        sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='创建时间'),
        sa.Column('updated_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW() ON UPDATE NOW()'), comment='更新时间'),
        sa.ForeignKeyConstraint(['project_id'], ['vwed_script_project.id'], ),
        sa.PrimaryKeyConstraint('id'),
        comment='脚本文件表'
    )
    
    # 创建脚本注册中心表
    op.create_table('vwed_script_registry',
        sa.Column('id', sa.Integer(), nullable=False, comment='注册记录ID'),
        sa.Column('script_id', sa.String(255), nullable=False, comment='脚本实例ID'),
        sa.Column('file_id', sa.Integer(), nullable=False, comment='脚本文件ID'),
        sa.Column('script_path', sa.String(500), nullable=False, comment='脚本相对路径'),
        sa.Column('status', sa.String(20), nullable=False, server_default='starting', comment='运行状态'),
        sa.Column('process_id', sa.String(50), nullable=True, comment='进程ID'),
        sa.Column('host_info', sa.JSON(), nullable=True, comment='主机信息'),
        sa.Column('start_params', sa.JSON(), nullable=True, comment='启动参数'),
        sa.Column('resource_limits', sa.JSON(), nullable=True, comment='资源限制配置'),
        sa.Column('performance_stats', sa.JSON(), nullable=True, comment='性能统计信息'),
        sa.Column('error_message', sa.Text(), nullable=True, comment='错误信息'),
        sa.Column('api_count', sa.Integer(), nullable=True, server_default='0', comment='注册的API数量'),
        sa.Column('function_count', sa.Integer(), nullable=True, server_default='0', comment='注册的函数数量'),
        sa.Column('event_count', sa.Integer(), nullable=True, server_default='0', comment='注册的事件监听器数量'),
        sa.Column('timer_count', sa.Integer(), nullable=True, server_default='0', comment='注册的定时任务数量'),
        sa.Column('last_heartbeat', sa.DateTime(), nullable=True, comment='最后心跳时间'),
        sa.Column('started_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='启动时间'),
        sa.Column('stopped_at', sa.DateTime(), nullable=True, comment='停止时间'),
        sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='创建时间'),
        sa.Column('updated_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW() ON UPDATE NOW()'), comment='更新时间'),
        sa.ForeignKeyConstraint(['file_id'], ['vwed_script_file.id'], ),
        sa.PrimaryKeyConstraint('id'),
        sa.UniqueConstraint('script_id'),
        comment='脚本注册中心表'
    )
    
    # 创建脚本执行日志表
    op.create_table('vwed_script_execution_log',
        sa.Column('id', sa.Integer(), nullable=False, comment='日志ID'),
        sa.Column('script_id', sa.String(255), nullable=False, comment='脚本实例ID'),
        sa.Column('file_id', sa.Integer(), nullable=False, comment='脚本文件ID'),
        sa.Column('execution_type', sa.String(50), nullable=False, comment='执行类型'),
        sa.Column('function_name', sa.String(255), nullable=True, comment='执行的函数名'),
        sa.Column('input_params', sa.JSON(), nullable=True, comment='输入参数'),
        sa.Column('output_result', sa.JSON(), nullable=True, comment='输出结果'),
        sa.Column('status', sa.String(20), nullable=False, comment='执行状态'),
        sa.Column('error_message', sa.Text(), nullable=True, comment='错误信息'),
        sa.Column('error_traceback', sa.Text(), nullable=True, comment='错误堆栈'),
        sa.Column('start_time', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='开始时间'),
        sa.Column('end_time', sa.DateTime(), nullable=True, comment='结束时间'),
        sa.Column('duration_ms', sa.Integer(), nullable=True, comment='执行时长'),
        sa.Column('memory_usage_mb', sa.Float(), nullable=True, comment='内存使用'),
        sa.Column('cpu_usage_percent', sa.Float(), nullable=True, comment='CPU使用率'),
        sa.Column('log_level', sa.String(20), nullable=True, server_default='INFO', comment='日志级别'),
        sa.Column('tags', sa.JSON(), nullable=True, comment='标签信息'),
        sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='创建时间'),
        sa.ForeignKeyConstraint(['file_id'], ['vwed_script_file.id'], ),
        sa.PrimaryKeyConstraint('id'),
        comment='脚本执行日志表'
    )
    
    # 创建API注册记录表
    op.create_table('vwed_script_api_registration',
        sa.Column('id', sa.Integer(), nullable=False, comment='注册记录ID'),
        sa.Column('script_id', sa.String(255), nullable=False, comment='脚本实例ID'),
        sa.Column('file_id', sa.Integer(), nullable=False, comment='脚本文件ID'),
        sa.Column('route_path', sa.String(500), nullable=False, comment='路由路径'),
        sa.Column('http_method', sa.String(20), nullable=False, comment='HTTP方法'),
        sa.Column('handler_name', sa.String(255), nullable=False, comment='处理函数名'),
        sa.Column('description', sa.Text(), nullable=True, comment='接口描述'),
        sa.Column('parameters', sa.JSON(), nullable=True, comment='接口参数定义'),
        sa.Column('response_schema', sa.JSON(), nullable=True, comment='响应格式定义'),
        sa.Column('is_active', sa.Boolean(), nullable=True, server_default='1', comment='是否激活'),
        sa.Column('call_count', sa.Integer(), nullable=True, server_default='0', comment='调用次数'),
        sa.Column('last_called_at', sa.DateTime(), nullable=True, comment='最后调用时间'),
        sa.Column('average_response_time_ms', sa.Integer(), nullable=True, comment='平均响应时间'),
        sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='注册时间'),
        sa.ForeignKeyConstraint(['file_id'], ['vwed_script_file.id'], ),
        sa.PrimaryKeyConstraint('id'),
        comment='API注册记录表'
    )
    
    # 创建函数注册记录表
    op.create_table('vwed_script_function_registration',
        sa.Column('id', sa.Integer(), nullable=False, comment='注册记录ID'),
        sa.Column('script_id', sa.String(255), nullable=False, comment='脚本实例ID'),
        sa.Column('file_id', sa.Integer(), nullable=False, comment='脚本文件ID'),
        sa.Column('function_name', sa.String(255), nullable=False, comment='函数名'),
        sa.Column('handler_name', sa.String(255), nullable=False, comment='处理函数名'),
        sa.Column('description', sa.Text(), nullable=True, comment='函数描述'),
        sa.Column('parameters', sa.JSON(), nullable=True, comment='参数定义'),
        sa.Column('return_schema', sa.JSON(), nullable=True, comment='返回值格式定义'),
        sa.Column('is_async', sa.Boolean(), nullable=True, server_default='0', comment='是否为异步函数'),
        sa.Column('is_active', sa.Boolean(), nullable=True, server_default='1', comment='是否激活'),
        sa.Column('call_count', sa.Integer(), nullable=True, server_default='0', comment='调用次数'),
        sa.Column('last_called_at', sa.DateTime(), nullable=True, comment='最后调用时间'),
        sa.Column('average_execution_time_ms', sa.Integer(), nullable=True, comment='平均执行时间'),
        sa.Column('success_count', sa.Integer(), nullable=True, server_default='0', comment='成功执行次数'),
        sa.Column('error_count', sa.Integer(), nullable=True, server_default='0', comment='错误次数'),
        sa.Column('tags', sa.JSON(), nullable=True, comment='函数标签'),
        sa.Column('created_at', sa.DateTime(), nullable=False, server_default=sa.text('NOW()'), comment='注册时间'),
        sa.ForeignKeyConstraint(['file_id'], ['vwed_script_file.id'], ),
        sa.PrimaryKeyConstraint('id'),
        comment='函数注册记录表'
    )
    
    # 创建索引
    op.create_index('idx_script_file_project_path', 'vwed_script_file', ['project_id', 'file_path'])
    op.create_index('idx_script_registry_script_id', 'vwed_script_registry', ['script_id'])
    op.create_index('idx_script_registry_status', 'vwed_script_registry', ['status'])
    op.create_index('idx_execution_log_script_id', 'vwed_script_execution_log', ['script_id'])
    op.create_index('idx_execution_log_status', 'vwed_script_execution_log', ['status'])
    op.create_index('idx_api_registration_script_id', 'vwed_script_api_registration', ['script_id'])
    op.create_index('idx_api_registration_route', 'vwed_script_api_registration', ['route_path', 'http_method'])
    op.create_index('idx_function_registration_script_id', 'vwed_script_function_registration', ['script_id'])
    op.create_index('idx_function_registration_name', 'vwed_script_function_registration', ['function_name'])


def downgrade():
    """删除脚本引擎相关表"""
    
    # 删除索引
    op.drop_index('idx_function_registration_name', table_name='vwed_script_function_registration')
    op.drop_index('idx_function_registration_script_id', table_name='vwed_script_function_registration')
    op.drop_index('idx_api_registration_route', table_name='vwed_script_api_registration')
    op.drop_index('idx_api_registration_script_id', table_name='vwed_script_api_registration')
    op.drop_index('idx_execution_log_status', table_name='vwed_script_execution_log')
    op.drop_index('idx_execution_log_script_id', table_name='vwed_script_execution_log')
    op.drop_index('idx_script_registry_status', table_name='vwed_script_registry')
    op.drop_index('idx_script_registry_script_id', table_name='vwed_script_registry')
    op.drop_index('idx_script_file_project_path', table_name='vwed_script_file')
    
    # 删除表（按依赖关系逆序删除）
    op.drop_table('vwed_script_function_registration')
    op.drop_table('vwed_script_api_registration')
    op.drop_table('vwed_script_execution_log')
    op.drop_table('vwed_script_registry')
    op.drop_table('vwed_script_file')
    op.drop_table('vwed_script_project')