#!/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.

"""Reading an existing debian/copyright file (the persistence seam).

This module owns the file I/O that turns a path into a parsed Copyright (or the
header's Files-Excluded patterns). Keeping it separate from copyright_processor
leaves the Copyright class to its one job -- matching files to groups -- rather
than also reading files off disk. The dependency is one-way: this module imports
Copyright (and the shared path resolver), never the reverse.
"""

from __future__ import annotations

import debian.copyright as dc

from decopy.common.core_types import LicenseRegistry, Options
from decopy.dep5doc.copyright_processor import Copyright, resolve_copyright_path


def read_copyright(
    options: Options, registry: LicenseRegistry | None = None
) -> Copyright:
    """Read the existing copyright file into a Copyright, or an empty one.

    Returns an empty Copyright when the file is absent or not machine-readable.
    """
    filepath = resolve_copyright_path(options)

    if not filepath.exists():
        return Copyright(registry=registry)

    try:
        with filepath.open() as c:
            return Copyright(dc.Copyright(c, strict=False), registry=registry)
    except (dc.NotMachineReadableError, ValueError):
        return Copyright(registry=registry)


def _read_header(options: Options) -> dc.Header | None:
    """The existing copyright file's header, or None if absent/unparseable.

    Read before the tree walk so the Files-Excluded patterns are available to
    prune the walk.
    """
    filepath = resolve_copyright_path(options)
    if not filepath.exists():
        return None
    try:
        with filepath.open() as c:
            return dc.Copyright(c, strict=False).header
    except (dc.NotMachineReadableError, ValueError):
        return None


def read_files_excluded(options: Options) -> tuple[str, ...]:
    """The header Files-Excluded patterns, whitespace-split, or () if absent.

    DEP-5 lists the repack patterns whitespace-separated (possibly spanning
    continuation lines); python-debian returns the raw lines, so each is split
    into individual patterns.
    """
    header = _read_header(options)
    if header is None:
        return ()
    return tuple(
        pattern for line in (header.files_excluded or ()) for pattern in line.split()
    )
