#!/usr/bin/env python3
"""Frontend container entrypoint.

Substitutes __SENTRY_*__ placeholders in `scorm_shared/sentry-config.template.js`
with the values of the matching environment variables at container startup,
writing the result to `scorm_shared/sentry-config.js`. This keeps the DSN out
of the source HTML and allows per-instance overrides without rebuilding the
image — set SENTRY_DSN="" in the env to disable Sentry entirely.

After substitution, exec's whatever command was given (typically the http.server).
"""

from __future__ import annotations

import json
import os
import re
import sys
from pathlib import Path

TEMPLATE = Path("/app/scorm_shared/sentry-config.template.js")
OUTPUT = Path("/app/scorm_shared/sentry-config.js")

# Single regex over all placeholder names — one pass so a substituted value
# can never collide with another placeholder still pending replacement.
# Strings appear in the template wrapped in quotes ("__SENTRY_DSN__"); the
# replacement value is a complete JS literal (quoted string OR bare number).
_STRING_PLACEHOLDERS = {
    "__SENTRY_DSN__": ("SENTRY_DSN", ""),
    "__SENTRY_ENVIRONMENT__": ("SENTRY_ENVIRONMENT", "production"),
}
_NUMBER_PLACEHOLDERS = {
    "__SENTRY_TRACES_SAMPLE_RATE__": ("SENTRY_TRACES_SAMPLE_RATE", "0.2"),
    "__SENTRY_REPLAYS_SESSION_SAMPLE_RATE__": ("SENTRY_REPLAYS_SESSION_SAMPLE_RATE", "0.1"),
    "__SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE__": ("SENTRY_REPLAYS_ON_ERROR_SAMPLE_RATE", "1.0"),
}
# `"__FOO__"` (string, with quotes) matched first; bare `__FOO__` second.
_PATTERN = re.compile(r'"(__[A-Z_]+__)"|(__[A-Z_]+__)')


def _value_for(placeholder: str) -> str:
    """Return the JS literal that should replace ``placeholder`` (with surrounding
    quotes for strings, bare number for floats, or the literal back for unknowns)."""
    if placeholder in _STRING_PLACEHOLDERS:
        env_var, default = _STRING_PLACEHOLDERS[placeholder]
        return json.dumps(os.environ.get(env_var, default))
    if placeholder in _NUMBER_PLACEHOLDERS:
        env_var, default = _NUMBER_PLACEHOLDERS[placeholder]
        raw = os.environ.get(env_var, default)
        try:
            float(raw)
            return raw
        except ValueError:
            return default
    return placeholder  # unknown placeholder: leave the template literal alone


def _render() -> str:
    def _sub(match: re.Match[str]) -> str:
        quoted, bare = match.group(1), match.group(2)
        return _value_for(quoted) if quoted else _value_for(bare)

    return _PATTERN.sub(_sub, TEMPLATE.read_text())


def main() -> None:
    if TEMPLATE.exists():
        OUTPUT.write_text(_render())
        print(f"[entrypoint] wrote {OUTPUT} (SENTRY_DSN={'set' if os.environ.get('SENTRY_DSN') else 'empty'})", file=sys.stderr)
    else:
        print(f"[entrypoint] WARNING: template missing at {TEMPLATE}", file=sys.stderr)

    # Exec the rest of the command line — typically the http.server.
    if len(sys.argv) < 2:
        print("[entrypoint] no command supplied", file=sys.stderr)
        sys.exit(1)
    os.execvp(sys.argv[1], sys.argv[1:])


if __name__ == "__main__":
    main()
