# Copyright (C) 2026 Wilhelmus Dingenus de Pooter
# SPDX-License-Identifier: GPL-3.0-or-later
"""
sourceval/checks.py — the four reconciliation checks as report metadata.
================================================================================

These reuse the Auditor's ``CheckMeta`` / ``Finding`` / ``Report`` machinery so
the Source Validator produces the same HTML/CSV report and flags-layer the
Auditor does. They are *not* registered in the S-58 REGISTRY (they are not S-58
checks); they are standalone metadata objects, each with a stable plain-language
slug as its identity, mirroring the Auditor's naming discipline.

Severities are a sensible starting point and are expected to be tuned against
operational experience:
  * presence-in-source-not-chart → ERROR   (the chart is missing something real)
  * presence-in-chart-not-source → WARNING (could be source lag, not a chart bug)
  * attribute mismatch           → ERROR   (the chart disagrees with the source)
  * identity displaced           → WARNING (same name, different place — review)
"""

try:                                   # QGIS package import
    from ..validation.engine import CheckMeta, Severity
except ImportError:                    # headless harness
    from validation.engine import CheckMeta, Severity

# number is a citation slot; Source-Validation checks use an "SRC.n" tag rather
# than an S-58 number. name is the stable documentation slug (group/phrase).
IN_SOURCE_NOT_CHART = CheckMeta(
    number="SRC.1", severity=Severity.ERROR, category="Source validation",
    message="Feature present in the source but missing from the chart",
    solution="Add the missing feature to the ENC, or correct the source.",
    conformity="", func=None,
    name="source-validation/in-source-not-chart")

IN_CHART_NOT_SOURCE = CheckMeta(
    number="SRC.2", severity=Severity.WARNING, category="Source validation",
    message="Feature present in the chart but missing from the source",
    solution="Confirm the feature against the source; the source may be stale "
             "or the feature may be charted in error.",
    conformity="", func=None,
    name="source-validation/in-chart-not-source")

VALUE_MISMATCH = CheckMeta(
    number="SRC.3", severity=Severity.ERROR, category="Source validation",
    message="Co-located feature has a value that does not match the source",
    solution="Reconcile the differing attribute against the source of truth.",
    conformity="", func=None,
    name="source-validation/attribute-mismatch")

IDENTITY_DISPLACED = CheckMeta(
    number="SRC.4", severity=Severity.WARNING, category="Source validation",
    message="Same identifier appears at a different location in chart and source",
    solution="Check the position; one of the two records is misplaced.",
    conformity="", func=None,
    name="source-validation/identity-displaced")

GEOMETRY_DEVIATION = CheckMeta(
    number="SRC.5", severity=Severity.ERROR, category="Source validation",
    message="Charted line geometry deviates obviously from the source geometry",
    solution="Review the charted geometry against the source. Generalisation "
             "within tolerance never flags — only a contiguous stretch outside "
             "the tolerance corridor or a worst deviation beyond the cap does.",
    conformity="", func=None,
    name="source-validation/geometry-deviation")

ALL = [IN_SOURCE_NOT_CHART, IN_CHART_NOT_SOURCE, VALUE_MISMATCH,
       IDENTITY_DISPLACED]

# The line-geometry reconciliation runs these (SRC.3/SRC.4 attribute checks
# apply to matched line pairs exactly as to matched points).
LINE_CHECKS = [IN_SOURCE_NOT_CHART, IN_CHART_NOT_SOURCE, VALUE_MISMATCH,
               GEOMETRY_DEVIATION]
