"""No em dash in anything a shopper or the client reads; American spelling in every identifier.

The house style (agents.md, OVERNIGHT-RULES.md) had reached the tests and the client pages
but not the storefront: on 10 Sep fifteen remained in shopper-facing strings (the shared
title, the savings page, the airport picker's maximum notice, the search placeholder) and
one in a served product title the night before. This walks the SPA sources and the served
strings so the next one fails here. Comments may still use one; only string content is read.

Stream L adds the Python files it created: no em dash in their strings, and `colour` and
`flavour` in no identifier, column name, key token or alias row there or in `VARIATION_KINDS`
(rian, 14 Sep: "shade" is a shop word for the kind `color`, American spelling in code).
"""

import pathlib
import re

from app.services.lines import VARIATION_KINDS
from app.services.seo import DEFAULT_TITLE

MAIN = pathlib.Path(__file__).resolve().parents[1]
WEB = MAIN / "web"
COMMENT = re.compile(r"/\*.*?\*/|^\s*//.*$|^\s*\*.*$", re.S | re.M)
PY_COMMENT = re.compile(r'^\s*#.*$|"""(?:.|\n)*?"""', re.M)
# The Python files this stream created; a new one is added here when it lands.
STREAM_L_FILES = ("quantity.py", "overrides.py", "collected.py", "listings_table.py", "merge_desk.py")
BRITISH = re.compile(r"colour|flavour", re.I)


def sources():
    for path in sorted((WEB / "src").rglob("*")):
        # The vendored packs (src/vendor) are byte-identical to their sources and never edited;
        # a pack string that could reach the client is overridden through a prop where it
        # carries an em dash (the thread starter's hint), so DFP's own files are the test.
        if "vendor" in path.relative_to(WEB / "src").parts:
            continue
        if path.suffix in (".ts", ".tsx") and path.name != "schema.ts":
            yield path
    yield WEB / "index.html"


def python_sources():
    for name in STREAM_L_FILES:
        path = MAIN / "app" / "services" / name
        if path.exists():
            yield path


def test_no_em_dash_outside_comments():
    offenders = []
    for path in sources():
        text = COMMENT.sub("", path.read_text())
        for number, line in enumerate(text.splitlines(), 1):
            if "—" in line:
                offenders.append(f"{path.relative_to(WEB)}:{number}: {line.strip()[:80]}")
    for path in python_sources():
        text = PY_COMMENT.sub("", path.read_text())
        for number, line in enumerate(text.splitlines(), 1):
            if "—" in line:
                offenders.append(f"{path.relative_to(MAIN)}:{number}: {line.strip()[:80]}")
    assert not offenders, "\n".join(offenders)


def test_served_titles_carry_none():
    assert "—" not in DEFAULT_TITLE


def test_american_spelling_in_every_identifier_the_stream_created():
    """`colour` and `flavour` may appear only inside a quoted string or a comment (a shop's own
    wording, "Colour Riche", is data); never in code."""
    offenders = []
    for path in python_sources():
        text = PY_COMMENT.sub("", path.read_text())
        text = re.sub(r"'[^'\n]*'|\"[^\"\n]*\"", "''", text)
        for number, line in enumerate(text.splitlines(), 1):
            if BRITISH.search(line):
                offenders.append(f"{path.relative_to(MAIN)}:{number}: {line.strip()[:80]}")
    assert not offenders, "\n".join(offenders)
    assert not any(BRITISH.search(kind) for kind in VARIATION_KINDS)
    assert "color" in VARIATION_KINDS and "flavor" in VARIATION_KINDS
