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

"""
Group interface and data contracts extracted from dep5.py

This module defines the interfaces and data structures that Group classes
must implement, enabling better separation of concerns and testing.
"""

from __future__ import annotations

import collections.abc as abc
import typing as t

import debian.copyright as dc

from .core_types import CopyrightHolder, License, Options

if t.TYPE_CHECKING:
    from .group import FileGroup
    from .holders import CopyrightHolders
    from .nodes import FileInfo


@t.runtime_checkable
class LicenseKeyed(t.Protocol):
    """Something that can report a license key - a Group, seen from a file.

    This is the only part of a group a FileInfo needs from its existing_group,
    so that field depends on this rather than on the full GroupProtocol.
    """

    def get_license_key(self) -> str:
        """Get the license key."""
        ...


@t.runtime_checkable
class GroupProtocol(LicenseKeyed, t.Protocol):
    """
    Protocol defining the interface that all Group classes must implement.

    This protocol allows for different Group implementations while
    maintaining a consistent interface.
    """

    @property
    def license(self) -> str: ...

    key: tuple[str, tuple[str, ...] | None, str | None] | None
    position: int
    files: FileGroup
    copyrights: CopyrightHolders
    licenses: dict[str, License]
    license_filenames: set[str]
    comments: list[str]
    stored: dc.FilesParagraph | None

    def add_file(self, fileinfo: FileInfo) -> None:
        """Add a file to this group."""
        ...

    def add_copyrights(self, copyrights: abc.Iterable[CopyrightHolder]) -> None:
        """Add copyrights to this group."""
        ...

    def get_key(
        self,
        options: Options,
        *,
        ignore_copyright: bool = False,
    ) -> tuple[str, tuple[str, ...] | None, str | None]:
        """Get the key for this group based on options."""
        ...

    def copyright_block_valid(self) -> bool:
        """Check if this group can generate a valid copyright block."""
        ...

    def get_comments(self) -> str:
        """Get the assembled comment text for this group."""
        ...

    def sort_key(self, options: Options) -> tuple[int, int, int, int, t.Any]:
        """Get the sort key for this group."""
        ...
