# Copyright (C) 2026 GoodData Corporation

"""Shared types and tokenization for rules retrieval scoring."""

from __future__ import annotations

import re
from dataclasses import dataclass, field

from aida_mcp.tools.rules.embeddings.chunker import RuleChunk
from aida_mcp.tools.rules.store import Rule


def _empty_str_set() -> set[str]:
    return set()


def _empty_chunk_list() -> list[RuleChunk]:
    return []


def _empty_reason_list() -> list[str]:
    return []


@dataclass
class ScoredRule:
    """A rule with its relevance score."""

    rule: Rule
    score: float
    matched_tokens: set[str] = field(default_factory=_empty_str_set)
    bm25_score: float = 0.0
    embedding_score: float = 0.0
    matched_chunks: list[RuleChunk] = field(default_factory=_empty_chunk_list)
    injected: bool = False  # True if this rule was injected by routing (not retrieved by scoring)
    selection_reasons: list[str] = field(default_factory=_empty_reason_list)
    required_by_rule_ids: list[str] = field(default_factory=_empty_reason_list)


# Minimal stopwords - only articles/prepositions that never help retrieval.
STOPWORDS: frozenset[str] = frozenset(
    {
        "the",
        "and",
        "for",
        "with",
        "from",
        "into",
        "about",
        "that",
        "this",
        "are",
        "was",
        "were",
        "been",
        "being",
        "have",
        "has",
        "had",
        "does",
        "did",
        "will",
        "would",
        "could",
        "should",
        "can",
        "may",
        "might",
        "must",
        "shall",
        "need",
        "but",
        "not",
        "also",
        "just",
        "only",
        "how",
        "what",
        "when",
        "where",
        "why",
        "which",
        "who",
        "whom",
    }
)


def tokenize_query(query: str) -> set[str]:
    """Tokenize a search query into meaningful terms, filtering minimal stopwords."""
    query = re.sub(r"[`#*_\[\]()]", " ", query.lower())
    tokens = set(re.findall(r"[a-z0-9][\w-]*", query))
    return {t for t in tokens if len(t) > 2 and t not in STOPWORDS}
