"""Deterministic, offline hashing embedder.

Maps text to a fixed-dimension unit vector via signed feature hashing of its
tokens. No network or model needed, so the full RAG pipeline runs locally and in
tests, and texts sharing vocabulary land near each other (good enough for
retrieval relevance in dev/CI).
"""

from __future__ import annotations

import hashlib
import math
import re

_TOKEN_RE = re.compile(r"[a-z0-9]+")


def _tokenize(text: str) -> list[str]:
    return _TOKEN_RE.findall(text.lower())


class HashingEmbedder:
    provider = "hashing"

    def __init__(self, *, dim: int = 256, model: str = "hashing-v1") -> None:
        self._dim = dim
        self.model = model

    @property
    def dimension(self) -> int:
        return self._dim

    def _embed_one(self, text: str) -> list[float]:
        vec = [0.0] * self._dim
        for token in _tokenize(text):
            digest = hashlib.sha1(token.encode("utf-8")).digest()
            idx = int.from_bytes(digest[:4], "big") % self._dim
            sign = 1.0 if digest[4] & 1 else -1.0
            vec[idx] += sign
        norm = math.sqrt(sum(x * x for x in vec))
        if norm == 0.0:
            return vec
        return [x / norm for x in vec]

    def embed(self, texts: list[str]) -> list[list[float]]:
        return [self._embed_one(t) for t in texts]
