#!/usr/bin/env python3
# Copyright: 2026, Maximiliano Curia <maxy@debian.org>
#
# License: ISC
#  Permission to use, copy, modify, and/or distribute this software for any
#  purpose with or without fee is hereby granted, provided that the above
#  copyright notice and this permission notice appear in all copies.
#  .
#  THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
#  REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
#  AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
#  INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
#  LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
#  OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
#  PERFORMANCE OF THIS SOFTWARE.

"""Tests for scripts/spdx_template_as_re.py's template-analysis helpers."""

from __future__ import annotations

import json
import sys
from pathlib import Path

import pytest
import regex as rex

ROOT = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(ROOT / "scripts"))

import spdx_template_as_re as tar  # noqa: E402

from decopy.licensing import licenses  # noqa: E402

LICENSES_DIR = ROOT / "tests" / "testdata" / "licenses"


@pytest.mark.parametrize("license_id", ["MIT", "ISC", "HPND", "0BSD"])
def test_template_to_regex_matches_real_license_text(license_id: str) -> None:
    data = json.loads((LICENSES_DIR / f"{license_id}.json").read_text())
    regex_str = tar.template_to_regex(data["standardLicenseTemplate"])
    pattern = rex.compile(regex_str, rex.IGNORECASE | rex.DOTALL)
    assert pattern.search(licenses.clean_comments(data["licenseText"]))


def test_template_literal_spans_splits_on_var_token() -> None:
    template = 'Alpha <<var;name="x";original="Y";match=".*">> beta.'
    assert tar.template_literal_spans(template) == ["Alpha", "beta."]


def test_template_literal_spans_splits_on_paragraph_break() -> None:
    template = "Paragraph one is here.\n\nParagraph two follows."
    assert tar.template_literal_spans(template) == [
        "Paragraph one is here.",
        "Paragraph two follows.",
    ]


def test_template_literal_spans_preserves_punctuation() -> None:
    # A stripped quote must not silently become whitespace: the live source
    # this is meant to search still has the quote character, not a space.
    template = 'files (the "Software"), to deal'
    assert tar.template_literal_spans(template) == ['files (the "Software"), to deal']


def test_template_literal_spans_collapses_wrapped_whitespace() -> None:
    template = "one\n  two   three"
    assert tar.template_literal_spans(template) == ["one two three"]


def test_is_dubious_flags_placeholder_shapes() -> None:
    assert tar.is_dubious("copy of [NAME] here")
    assert tar.is_dubious("fill in the ____ blank")
    assert tar.is_dubious("insert the LIST of names")
    assert not tar.is_dubious("ordinary licence prose with no placeholders")


def test_distinctive_window_returns_none_when_fully_contained_elsewhere() -> None:
    span = "this is a long enough literal phrase for testing purposes here today"
    other = span + " and then some more words after it"
    assert tar.distinctive_window([span], [other]) is None


def test_distinctive_window_skips_dubious_but_finds_a_clean_window() -> None:
    span = (
        "a prefix long enough to pass the minimum length before any dubious text "
        "then a dubious [PLACEHOLDER] marker right here and then a clean suffix "
        "that is also long enough on its own to qualify as a window by itself"
    )
    window = tar.distinctive_window([span], [])
    assert window is not None
    assert "[PLACEHOLDER]" not in window


def test_distinctive_window_never_crosses_a_span_boundary() -> None:
    spans = ["short end of one paragraph here", "start of the next paragraph here"]
    window = tar.distinctive_window(spans, [], min_len=10, max_len=200)
    assert window is not None
    assert window in spans[0] or window in spans[1]


def test_window_to_regexp_query_tolerates_rewrapped_whitespace() -> None:
    window = 'the "Software" (as defined)'
    query = tar.window_to_regexp_query(window)
    pattern = rex.compile(query)
    assert pattern.search('the "Software"\n   (as   defined)')
    assert pattern.search("the (Software) (as defined)") is None
