#!/usr/bin/env python3

# Unit tests for the extracted explain-mode staleness detectors.
# 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.

"""Direct unit tests for decopy.dep5doc.staleness.

These functions were extracted from copyright_processor and used to be private,
tested only through Copyright. Now that they are a module's public API, pin their
contract directly.
"""

import debian.copyright as dc

from decopy.dep5doc import staleness
from decopy.dep5doc.delta import (
    RELICENSED,
    STALE_PARAGRAPH,
    STALE_PATTERN,
    SUB_LICENSE,
    DeltaReport,
)
from decopy.fstree import nodes
from decopy.grouping.grouping import GroupKey


def test_record_relicensed_skips_packaging_files():
    report = DeltaReport()
    fileinfo = nodes.FileInfo(parent=None, name="debian/rules")
    keys = (
        GroupKey("Apache-2.0", None, "debian/rules"),
        GroupKey("GPL-2+", None, "debian/rules"),
    )
    staleness.record_relicensed(report, fileinfo, keys)
    assert report.is_empty()


def test_record_relicensed_ignores_path_only_difference():
    report = DeltaReport()
    fileinfo = nodes.FileInfo(parent=None, name="src/a.c")
    # Same license and copyright, different path -> not a relicense signal.
    keys = (GroupKey("MIT", None, "src/a.c"), GroupKey("MIT", None, "src/b.c"))
    staleness.record_relicensed(report, fileinfo, keys)
    assert report.is_empty()


def test_record_relicensed_records_a_license_change():
    report = DeltaReport()
    fileinfo = nodes.FileInfo(parent=None, name="src/a.c")
    keys = (
        GroupKey("Apache-2.0", None, "src/a.c"),
        GroupKey("GPL-2+", None, "src/a.c"),
    )
    staleness.record_relicensed(report, fileinfo, keys)
    entries = report.by_kind()[RELICENSED]
    assert len(entries) == 1
    entry = entries[0]
    assert entry.path == "src/a.c"
    assert entry.was == "GPL-2+"
    assert entry.now == "Apache-2.0"
    assert entry.sub_kind == SUB_LICENSE


def test_record_stale_patterns_dedups_dead_patterns_in_order():
    report = DeltaReport()
    paragraph = dc.FilesParagraph.create(
        ["*.c", "*.h", "*.py"], "2020 Alice", dc.License("MIT")
    )
    # Only *.c matched; *.h and *.py are dead, one entry each, declared order.
    staleness.record_stale_patterns(report, paragraph, ["*.c"])
    entries = report.by_kind()[STALE_PATTERN]
    assert [e.pattern for e in entries] == ["*.h", "*.py"]
    assert all(e.paragraph_license == "MIT" for e in entries)


def test_record_stale_paragraph_attributes_matching_deletions():
    report = DeltaReport()
    paragraph = dc.FilesParagraph.create(["docs/*"], "2020 Alice", dc.License("GPL-2+"))
    staleness.record_stale_paragraph(
        report, paragraph, deleted=("docs/old.txt", "src/keep.c")
    )
    entries = report.by_kind()[STALE_PARAGRAPH]
    assert len(entries) == 1
    entry = entries[0]
    assert entry.paragraph_license == "GPL-2+"
    # Only the deleted path matching the paragraph's pattern is attributed.
    assert entry.deleted_files == ("docs/old.txt",)
