import logging
from copy import (
    deepcopy,
)

from bs4 import (
    BeautifulSoup,
)
from packageurl import (
    PackageURL,
)
from pydantic import (
    ValidationError,
)

from labels.artifact.relationship import (
    Relationship,
)
from labels.file.dependency_type import (
    DependencyType,
)
from labels.file.location_read_closer import (
    LocationReadCloser,
)
from labels.file.resolver import (
    Resolver,
)
from labels.model.core import (
    Language,
    Package,
    PackageType,
)
from labels.pkg.cataloger.generic.parser import (
    Environment,
)
from labels.utils.strings import format_exception

LOGGER = logging.getLogger(__name__)


def parse_dotnet_pkgs_config(
    _resolver: Resolver | None,
    _env: Environment | None,
    reader: LocationReadCloser,
) -> tuple[list[Package], list[Relationship]]:
    root = BeautifulSoup(reader.read_closer.read(), features="html.parser")
    packages = []

    for pkg in root.find_all("package", recursive=True):
        name: str | None = pkg.get("id")
        version: str | None = pkg.get("version")

        if not name or not version:
            continue

        line = pkg.sourceline
        location = deepcopy(reader.location)
        if location.coordinates:
            location.coordinates.line = line
            location.dependency_type = DependencyType.DIRECT

        try:
            packages.append(
                Package(
                    name=name,
                    version=version,
                    locations=[location],
                    language=Language.DOTNET,
                    licenses=[],
                    type=PackageType.DotnetPkg,
                    metadata=None,
                    p_url=PackageURL(
                        type="nuget",
                        namespace="",
                        name=name,
                        version=version,
                        qualifiers={},
                        subpath="",
                    ).to_string(),
                ),
            )
        except ValidationError as ex:
            LOGGER.warning(
                "Malformed package. Required fields are missing or data types are incorrect.",
                extra={
                    "extra": {
                        "exception": format_exception(str(ex)),
                        "location": location.path(),
                    },
                },
            )
            continue

    return packages, []
