"""Tool metadata definitions for the MCP server.

All 30 Tool(...) descriptor objects and the get_tools_meta() function.
"""
from mcp.types import Tool


def get_tools_meta() -> list[Tool]:
    """Return the list of Tool metadata objects for MCP server registration.

    Call this from :meth:`TLSAnalyzerMCPServer._setup_tools`.
    """
    return [
        Tool(
            name="load_data",
            description=(
                "加载匹配glob模式的CSV文件。自动检测每个文件的BOM，验证schema一致性，"
                "纵向合并，并将结果作为惰性数据集存储在会话存储中。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "csv_glob": {
                        "type": "string",
                        "description": "Glob pattern for CSV files (e.g. 'data/*.csv')",
                    },
                    "config_path": {
                        "type": "string",
                        "description": "Optional path to a YAML config file",
                    },
                    "encoding": {
                        "type": "string",
                        "description": "Fallback encoding when no BOM is found",
                        "default": "utf-8",
                    },
                    "delimiter": {
                        "type": "string",
                        "description": "Column delimiter",
                        "default": ",",
                    },
                    "schema_strict": {
                        "type": "boolean",
                        "description": "When True, raise on column mismatch; when False, merge leniently with nulls",
                        "default": False,
                    },
                    "recursive": {
                        "type": "boolean",
                        "description": "When True, use recursive glob for **/*.csv patterns",
                        "default": False,
                    },
                },
                "required": ["csv_glob"],
            },
        ),
        Tool(
            name="profile_data",
            description=(
                "计算数据集的每列统计信息和数值相关矩阵。结果自动截断至约16 KB以"
                "节省LLM上下文窗口空间。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {
                        "type": "string",
                        "description": "Dataset identifier from a previous load_data call",
                    },
                    "sample_size": {
                        "type": "integer",
                        "description": "Maximum rows to profile (sampled if larger)",
                        "default": 1000,
                    },
                    "columns": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "Columns to profile (default: all)",
                    },
                },
                "required": ["dataset_id"],
            },
        ),
        Tool(
            name="filter_data",
            description=(
                "对数据集应用列级过滤器，将结果存储为新的派生数据集。支持eq/neq/gt/gte/"
                "lt/lte/contains/not_contains/in/not_in/is_null/is_not_null运算符。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {
                        "type": "string",
                        "description": "Source dataset identifier",
                    },
                    "filters": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "column": {"type": "string"},
                                "op": {
                                    "type": "string",
                                    "enum": [
                                        "eq", "neq", "gt", "gte", "lt", "lte",
                                        "contains", "not_contains",
                                        "in", "not_in",
                                        "is_null", "is_not_null",
                                    ],
                                },
                                "value": {"description": "Operand value"},
                            },
                            "required": ["column", "op"],
                        },
                        "description": "List of filter expressions",
                    },
                    "logic": {
                        "type": "string",
                        "enum": ["and", "or"],
                        "description": "Combine filters with AND or OR logic",
                        "default": "and",
                    },
                },
                "required": ["dataset_id", "filters"],
            },
        ),
        Tool(
            name="preprocess_data",
            description=(
                "预处理选定列：标准化（StandardScaler）、独热编码、缺失值填充和列删除。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {
                        "type": "string",
                        "description": "Source dataset identifier",
                    },
                    "columns": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "Columns to preprocess",
                    },
                    "config": {
                        "type": "object",
                        "properties": {
                            "standardize": {
                                "type": "boolean",
                                "description": "Apply StandardScaler to numeric columns",
                                "default": False,
                            },
                            "onehot": {
                                "type": "boolean",
                                "description": "One-hot encode categorical columns",
                                "default": False,
                            },
                            "fillna": {
                                "type": "string",
                                "enum": ["mean", "median", "zero", "drop"],
                                "description": "Missing value strategy",
                            },
                            "drop": {
                                "type": "array",
                                "items": {"type": "string"},
                                "description": "Columns to drop entirely",
                            },
                        },
                    },
                },
                "required": ["dataset_id", "columns"],
            },
        ),
        Tool(
            name="run_clustering",
            description=(
                "对选定列执行聚类。使用HDBSCAN（默认）或KMeans。特征在聚类前进行"
                "标准化缩放。返回聚类标签和质量指标。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {
                        "type": "string",
                        "description": "Dataset identifier",
                    },
                    "cluster_columns": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "Columns to use as clustering features",
                    },
                    "algorithm": {
                        "type": "string",
                        "enum": ["agglomerative", "hdbscan", "kmeans"],
                        "description": "Clustering algorithm (default: agglomerative/Ward)",
                        "default": "agglomerative",
                    },
                    "params": {
                        "type": "object",
                        "description": (
                            "Algorithm parameters. Agglomerative: n_clusters (5), metric ('euclidean'), "
                            "linkage ('ward'). HDBSCAN: min_cluster_size (5), "
                            "min_samples (None), metric ('euclidean'). "
                            "KMeans: n_clusters (3), random_state (42)."
                        ),
                    },
                    "random_state": {
                        "type": "integer",
                        "description": "Random seed for reproducibility",
                        "default": 42,
                    },
                },
                "required": ["dataset_id", "cluster_columns"],
            },
        ),
        Tool(
            name="evaluate_clustering",
            description=(
                "评估数据集的聚类结果。当前支持轮廓系数（silhouette）、Davies-Bouldin指数、"
                "Calinski-Harabasz指数、噪声比（noise_ratio）和簇大小（cluster_sizes）指标。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "cluster_result_id": {
                        "type": "string",
                        "description": "Result ID from run_clustering",
                    },
                    "dataset_id": {
                        "type": "string",
                        "description": "Original dataset for metric computation",
                    },
                    "metrics": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": (
                            "Metrics to compute. Options: silhouette, "
                            "davies_bouldin, calinski_harabasz, noise_ratio, "
                            "cluster_sizes (default: all)"
                        ),
                    },
                },
                "required": ["cluster_result_id", "dataset_id"],
            },
        ),
        Tool(
            name="extract_features",
            description=(
                "提取每个聚类的区分特征并自动保存到Django ORM（ClusterFeature模型）。"
                "使用z-score或ANOVA对每个聚类的特征重要性进行排序。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {
                        "type": "string",
                        "description": "Dataset containing the feature columns",
                    },
                    "cluster_result_id": {
                        "type": "string",
                        "description": "Result ID from run_clustering",
                    },
                    "top_k": {
                        "type": "integer",
                        "description": "Top distinguishing features per cluster",
                        "default": 10,
                    },
                    "method": {
                        "type": "string",
                        "enum": ["zscore", "anova"],
                        "description": "Method to rank feature importance",
                        "default": "zscore",
                    },
                    "save_to_db": {
                        "type": "boolean",
                        "description": "Save features to Django ORM if True",
                        "default": True,
                    },
                },
                "required": ["dataset_id", "cluster_result_id"],
            },
        ),
        Tool(
            name="export_results",
            description=(
                "将数据集或聚类结果以CSV或Parquet格式导出到磁盘。数据集物化后写入；"
                "聚类结果序列化为JSON。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "result_id": {
                        "type": "string",
                        "description": "Dataset ID or cluster result ID to export",
                    },
                    "output_path": {
                        "type": "string",
                        "description": "Output file path or directory",
                    },
                    "format": {
                        "type": "string",
                        "enum": ["csv", "parquet", "json"],
                        "description": "Output format",
                        "default": "csv",
                    },
                    "overwrite": {
                        "type": "boolean",
                        "description": "Overwrite existing file",
                        "default": False,
                    },
                },
                "required": ["result_id", "output_path"],
            },
        ),
        Tool(
            name="list_datasets",
            description="列出会话存储中的所有活跃数据集和结果。",
            inputSchema={
                "type": "object",
                "properties": {},
            },
        ),
        Tool(
            name="drop_dataset",
            description=(
                "从会话存储中移除数据集（或结果）并通过垃圾回收释放内存。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {
                        "type": "string",
                        "description": "Dataset or result identifier to remove",
                    },
                },
                "required": ["dataset_id"],
            },
        ),
        Tool(
            name="clone_dataset",
            description=(
                "浅拷贝数据集。由于LazyFrame是查询计划，不会复制实际数据。适用于分支分析。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {
                        "type": "string",
                        "description": "Source dataset identifier",
                    },
                },
                "required": ["dataset_id"],
            },
        ),
        Tool(
            name="filter_and_cluster",
            description=(
                "一步完成：先应用列级过滤器，再对过滤结果执行聚类。支持eq/neq/gt/gte/lt/lte/"
                "contains/not_contains/in/not_in/is_null/is_not_null运算符和HDBSCAN/KMeans聚类。"
                "自动选择数值列作为聚类特征。将过滤后的数据集和聚类结果都存储在会话中。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {
                        "type": "string",
                        "description": "Source dataset identifier",
                    },
                    "filters": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "properties": {
                                "column": {"type": "string"},
                                "op": {
                                    "type": "string",
                                    "enum": [
                                        "eq", "neq", "gt", "gte", "lt", "lte",
                                        "contains", "not_contains",
                                        "in", "not_in",
                                        "is_null", "is_not_null",
                                    ],
                                },
                                "value": {"description": "Operand value"},
                            },
                            "required": ["column", "op"],
                        },
                        "description": "List of filter expressions",
                    },
                    "logic": {
                        "type": "string",
                        "enum": ["and", "or"],
                        "description": "Combine filters with AND or OR logic",
                        "default": "and",
                    },
                    "algorithm": {
                        "type": "string",
                        "enum": ["agglomerative", "hdbscan", "kmeans"],
                        "description": "Clustering algorithm (default: agglomerative/Ward)",
                        "default": "agglomerative",
                    },
                    "params": {
                        "type": "object",
                        "description": (
                            "Algorithm parameters. Agglomerative: n_clusters (5), metric ('euclidean'), "
                            "linkage ('ward'). HDBSCAN: min_cluster_size (5), "
                            "min_samples (None), metric ('euclidean'). "
                            "KMeans: n_clusters (3), random_state (42)."
                        ),
                    },
                },
                "required": ["dataset_id", "filters"],
            },
        ),
        Tool(
            name="build_entity_profiles",
            description=(
                "按实体列（源IP、SNI等）分组原始流数据。自动检测实体列（如 src_ip, "
                "dst_ip, sni, host, mac, domain），按列分组并计算每个实体的聚合特征："
                "流数量、唯一端口数、TLS版本分布、字节总量、唯一目标数。"
                "生成的数据集每个实体一行。结果存储在会话中，可供后续 compute_scores 使用。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {
                        "type": "string",
                        "description": "Dataset ID from load_data or profile_data",
                    },
                    "entity_column": {
                        "type": "string",
                        "description": "Specific entity column to group by (e.g. 'src_ip')",
                    },
                    "entity_columns": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "Multiple entity columns to group by",
                    },
                    "auto_detect": {
                        "type": "boolean",
                        "description": "Auto-detect entity columns (IP, SNI, host, MAC, domain)",
                        "default": True,
                    },
                },
                "required": ["dataset_id"],
            },
        ),
        Tool(
            name="compute_scores",
            description=(
                "在实体数据上计算自适应代理/异常/威胁评分。从数据自动学习"
                "特征权重，计算加权代理评分（proxy_score）、基于IQR的风险等级"
                "（normal/watch/suspicious/critical）和威胁评分（threat_score）。"
                "返回评分摘要与阈值。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {
                        "type": "string",
                        "description": "Entity dataset ID from filter_and_cluster or a scored dataset",
                    },
                },
                "required": ["dataset_id"],
            },
        ),
        Tool(
            name="detect_anomalies",
            description=(
                "对已评分的实体数据运行孤立森林（Isolation Forest）异常检测。识别偏离"
                "正常模式的实体。分块处理以应对大数据集。返回异常实体ID列表。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {
                        "type": "string",
                        "description": "Scored entity dataset ID (after compute_scores)",
                    },
                    "contamination": {
                        "type": "number",
                        "description": "Expected proportion of anomalies (0.0-0.5)",
                        "default": 0.05,
                    },
                },
                "required": ["dataset_id"],
            },
        ),
        Tool(
            name="visualize_anomalies",
            description=(
                "为高风险实体生成UMAP-2D嵌入和聚类可视化数据。按风险等级和聚类着色。"
                "返回用于前端渲染的散点图JSON数据。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {
                        "type": "string",
                        "description": "Scored entity dataset ID (after compute_scores)",
                    },
                },
                "required": ["dataset_id"],
            },
        ),
        # ── Edge-case / Diagnostic tools (unexpected situations) ────────
        Tool(
            name="validate_data",
            description=(
                "诊断工具：检查数据质量问题——文件间schema一致性、缺失值比例、列类型冲突、"
                "编码问题和空列。当流水线步骤因schema错误失败，或怀疑CSV数据损坏/格式异常时使用。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {"type": "string", "description": "Dataset ID from load_data"},
                    "fix_issues": {"type": "boolean", "description": "Auto-fix schema inconsistencies", "default": False},
                },
                "required": ["dataset_id"],
            },
        ),
        Tool(
            name="explore_distributions",
            description=(
                "诊断工具：计算每列分布统计（唯一值计数、空值比例、最小/最大/均值/标准差、"
                "前10高频值、直方图分箱）。当聚类产生意外结果、实体检测失败，或需要在选择"
                "分析策略前了解数据时使用。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {"type": "string", "description": "Dataset ID from load_data or entity data"},
                    "columns": {"type": "array", "items": {"type": "string"},
                                "description": "Specific columns to analyze (default: auto-detect numeric)"},
                    "max_sample": {"type": "integer", "description": "Max rows to sample", "default": 10000},
                },
                "required": ["dataset_id"],
            },
        ),
        Tool(
            name="find_outliers",
            description=(
                "诊断工具：使用IQR方法检测数值列中的统计异常值。返回任何数值列超过中位数3倍IQR的行。"
                "当怀疑数据质量问题或极端值偏离分析时使用。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {"type": "string", "description": "Dataset ID from load_data"},
                    "columns": {"type": "array", "items": {"type": "string"},
                                "description": "Columns to check (default: all numeric)"},
                    "threshold": {"type": "number", "description": "IQR multiplier (default 3.0)", "default": 3.0},
                },
                "required": ["dataset_id"],
            },
        ),
        Tool(
            name="diagnose_clustering",
            description=(
                "诊断工具：当聚类产生太少/太多聚类、全部为噪声或轮廓系数低时——诊断原因。"
                "检查：特征方差、相关矩阵、特征降维分析、数据稀疏性，并建议参数调整"
                "（min_cluster_size、算法选择、特征选择）。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {"type": "string", "description": "Entity dataset ID"},
                    "cluster_result_id": {"type": "string", "description": "Cluster result ID from previous run_clustering"},
                },
                "required": ["dataset_id", "cluster_result_id"],
            },
        ),
        Tool(
            name="compare_datasets",
            description=(
                "诊断工具：比较两个数据集（如处理前/后，或两次不同运行）。报告schema差异、"
                "行数变化、列值分布偏移。用于验证处理步骤未损坏数据或比较不同运行的结果。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id_a": {"type": "string", "description": "First dataset ID"},
                    "dataset_id_b": {"type": "string", "description": "Second dataset ID"},
                },
                "required": ["dataset_id_a", "dataset_id_b"],
            },
        ),
        Tool(
            name="export_debug_sample",
            description=(
                "诊断工具：导出原始数据样本为JSON用于外部调试。当流水线深处发生错误且需要"
                "检查实际数据值时使用。返回前N行所有列。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {"type": "string", "description": "Dataset ID"},
                    "max_rows": {"type": "integer", "description": "Rows to export", "default": 50},
                },
                "required": ["dataset_id"],
            },
        ),
        Tool(
            name="repair_schema",
            description=(
                "诊断工具：通过对齐列名（不区分大小写合并、下划线/连字符规范化）并用空值填充"
                "缺失列，尝试修复文件间的schema不匹配。当load_data因CSV文件具有不同列集而"
                "失败时使用。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {"type": "string", "description": "Failed dataset ID from load_data"},
                },
                "required": ["dataset_id"],
            },
        ),
        # ── Read-only analysis tools (LLM deep-dive, no side effects) ────
        Tool(
            name="analyze_patterns",
            description=(
                "分析工具：检测流量模式——top源/目标IP、端口分布、TLS版本分布、协议混合。"
                "返回汇总统计。只读，不修改数据。用于了解高层流量结构。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {"type": "string", "description": "Dataset ID from load_data"},
                    "top_n": {"type": "integer", "description": "Number of top items per category", "default": 10},
                },
                "required": ["dataset_id"],
            },
        ),
        Tool(
            name="analyze_temporal",
            description=(
                "分析工具：分析随时间变化的流量——小时/日流量计数、繁忙时段、空闲时段。"
                "需要时间戳列。只读。用于了解时间相关模式和周期性。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {"type": "string", "description": "Dataset ID from load_data"},
                    "timestamp_column": {"type": "string", "description": "Column name for timestamps (auto-detected if omitted)"},
                },
                "required": ["dataset_id"],
            },
        ),
        Tool(
            name="analyze_fft",
            description=(
                "FFT频谱分析——从时间戳列提取周期模式和频率特征。适用于检测时间周期性"
                "（如每日/每周流量模式）。返回频率、幅度、top周期、频谱质心、周期性评分。"
                "只读，无副作用。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {
                        "type": "string",
                        "description": "Dataset ID from load_data",
                    },
                    "timestamp_column": {
                        "type": "string",
                        "description": "Column name containing timestamps or numeric time values",
                    },
                    "top_n": {
                        "type": "integer",
                        "description": "Number of top frequency peaks to return",
                        "default": 5,
                    },
                },
                "required": ["dataset_id", "timestamp_column"],
            },
        ),
        Tool(
            name="analyze_tls_health",
            description=(
                "分析工具：TLS安全态势评估——检查过时的TLS版本（1.0/1.1）、弱加密套件、"
                "证书问题、SNI异常。只读。用于评估流量的TLS安全性。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {"type": "string", "description": "Dataset ID from load_data"},
                },
                "required": ["dataset_id"],
            },
        ),
        Tool(
            name="analyze_geo_distribution",
            description=(
                "分析工具：流量地理分布——top源/目标国家、异常地点对（如不可能的行程）、"
                "ISP多样性。只读。需要国家或经纬度列。用于检测地理异常。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {"type": "string", "description": "Dataset ID from load_data"},
                },
                "required": ["dataset_id"],
            },
        ),
        Tool(
            name="analyze_entity_detail",
            description=(
                "分析工具：深入分析单个实体——其所有流、使用的TLS版本、目标多样性、时间模式、"
                "异常评分。只读。在compute_scores后调查特定可疑实体时使用。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {"type": "string", "description": "Entity dataset ID (after filter_and_cluster or compute_scores)"},
                    "entity_value": {"type": "string", "description": "Entity value to investigate (e.g. an IP address or SNI)"},
                },
                "required": ["dataset_id", "entity_value"],
            },
        ),
        Tool(
            name="compute_distance_matrix",
            description=(
                "LLM驱动工具：对数据集的每一行执行用户编写的Python函数，返回距离/相似度评分摘要。"
                "LLM提供函数体，签名格式为`def distance_fn(row: dict) -> float:`。执行器将其包装，"
                "在受限命名空间（仅math、numpy）中逐行运行，返回得分的最小/最大/均值/标准差以及"
                "评分行样本。用于现有工具无法表达的一次性度量、过滤或评分任务。"
            ),
            inputSchema={
                "type": "object",
                "properties": {
                    "dataset_id": {
                        "type": "string",
                        "description": "Source dataset identifier",
                    },
                    "python_function": {
                        "type": "string",
                        "description": (
                            "Body of a Python function with signature `def distance_fn(row: dict) -> float:`. "
                            "Example: \"return abs(row.get('col1', 0)) + row.get('col2', 0)\". "
                            "Available namespace: math, numpy (as np). No dangerous modules."
                        ),
                    },
                    "columns": {
                        "type": "array",
                        "items": {"type": "string"},
                        "description": "Columns to pass to the function (default: auto-detect numeric columns)",
                    },
                    "max_sample": {
                        "type": "integer",
                        "description": "Maximum rows to evaluate (default 10000 for performance)",
                        "default": 10000,
                    },
                },
                "required": ["dataset_id", "python_function"],
            },
        ),
    ]
