#!/usr/bin/env python3
# Copyright: 2016, 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.

from __future__ import annotations

import collections.abc as abc
import re as reo
import typing as t

from decopy.common._regex import rex
from decopy.common.core_types import CopyrightHolder


class ReSub(t.NamedTuple):
    pattern: rex.Pattern[str] | reo.Pattern[str]
    repl: str


class ReSubGroup(t.NamedTuple):
    """Ordered group of ReSub rules; only the first matching rule fires."""

    subs: tuple[ReSub, ...]


class ReFlags(t.NamedTuple):
    re: str
    flags: rex.RegexFlag | reo.RegexFlag | int = rex.IGNORECASE


type ParseResult = tuple[list[CopyrightHolder], list[str]]


class ReLicense(t.NamedTuple):
    re: str
    license: str
    # get_detail returns the refined licence id, or None to suppress this whole
    # family (used when an aggregate/collection should be reported under one id
    # detected by another family).
    get_detail: (
        abc.Callable[[str, rex.Match[str] | reo.Match[str], str], str | None] | None
    ) = None
    re_flags: rex.RegexFlag | reo.RegexFlag = rex.IGNORECASE
    # Exception SUBS applied to a matched licence id (the " with X exception"
    # suffix). When None, find_licenses falls back to EXCEPTION_SUBS_MAP keyed by
    # family; carrying it on the row keeps the rule self-contained.
    exception_subs: tuple[ReSub | ReSubGroup, ...] | None = None
