#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
模块名称：deploy_script.py
模块描述：部署脚本配置数据库模型定义

作者：czj
创建日期：2026-08-12
最后修改：2026-08-12
"""

from datetime import datetime
from typing import Optional
from sqlalchemy import String, Integer, Text, JSON, DateTime, ForeignKey
from sqlalchemy.orm import Mapped, mapped_column, relationship

from app.database import Base
from app.utils.id_generator import generate_id


class DeployScript(Base):
    """
    部署脚本配置

    配置远程服务器上部署脚本的执行命令与交互式应答规则。
    脚本已存在于目标服务器上，本配置仅定义如何执行及如何应答交互提示。

    Attributes:
        id (str): 脚本配置唯一标识
        name (str): 脚本配置名称
        description (str): 描述
        server_id (str): 关联的目标服务器 ID
        remote_command (str): 远程执行命令
        work_dir (str): 远程工作目录
        timeout (int): 执行超时时间（秒）
        expect_answers (dict): 交互式应答规则配置
        created_at (datetime): 创建时间
        updated_at (datetime): 更新时间
    """

    __tablename__ = "deploy_scripts"

    id: Mapped[str] = mapped_column(
        String(64), primary_key=True, default=lambda: generate_id("script"),
        comment="脚本配置唯一标识"
    )
    name: Mapped[str] = mapped_column(
        String(200), nullable=False, comment="脚本配置名称"
    )
    description: Mapped[Optional[str]] = mapped_column(
        Text, nullable=True, comment="描述"
    )
    server_id: Mapped[str] = mapped_column(
        String(64), ForeignKey("deploy_servers.id", ondelete="CASCADE"),
        nullable=False, comment="关联的目标服务器 ID"
    )
    remote_command: Mapped[str] = mapped_column(
        String(1000), nullable=False, comment="远程执行命令"
    )
    work_dir: Mapped[Optional[str]] = mapped_column(
        String(500), nullable=True, comment="远程工作目录"
    )
    timeout: Mapped[int] = mapped_column(
        Integer, default=3600, comment="执行超时时间（秒）"
    )
    expect_answers: Mapped[dict] = mapped_column(
        JSON, default=list, comment="交互式应答规则配置"
    )
    created_at: Mapped[datetime] = mapped_column(
        DateTime, default=datetime.utcnow, comment="创建时间"
    )
    updated_at: Mapped[datetime] = mapped_column(
        DateTime, default=datetime.utcnow, onupdate=datetime.utcnow,
        comment="更新时间"
    )

    # 关联目标服务器
    server: Mapped["DeployServer"] = relationship(
        "DeployServer", back_populates="scripts"
    )

    # 关联执行记录
    executions: Mapped[list["DeployExecution"]] = relationship(
        "DeployExecution",
        back_populates="script",
        cascade="all, delete-orphan"
    )

    def __repr__(self) -> str:
        return f"<DeployScript(id={self.id}, name={self.name})>"

    def to_dict(self) -> dict:
        return {
            "id": self.id,
            "name": self.name,
            "description": self.description,
            "server_id": self.server_id,
            "server_name": self.server.name if self.server else "",
            "remote_command": self.remote_command,
            "work_dir": self.work_dir,
            "timeout": self.timeout,
            "expect_answers": self.expect_answers or [],
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "updated_at": self.updated_at.isoformat() if self.updated_at else None,
        }