import re
from copy import deepcopy

from labels.model.file import (
    DependencyType,
    Location,
    LocationReadCloser,
    Scope,
)
from labels.model.package import Language, Package, PackageType
from labels.model.relationship import Relationship
from labels.model.resolver import Resolver
from labels.parsers.cataloger.elixir.package import package_url
from labels.parsers.cataloger.generic.parser import Environment

MIX_LOCK_DEP: re.Pattern[str] = re.compile(r"^\"(?P<dep>[\w]*)\":\{(?P<info>.+)\},")


def build_location(
    reader: LocationReadCloser,
    line_number: int,
) -> Location:
    location = deepcopy(reader.location)
    location.scope = Scope.PROD
    if location.coordinates:
        location.coordinates.line = line_number
        location.dependency_type = DependencyType.DIRECT
    return location


def parse_mix_lock(
    _: Resolver | None,
    __: Environment | None,
    reader: LocationReadCloser,
) -> tuple[list[Package], list[Relationship]]:
    packages: list[Package] = []
    relationships: list[Relationship] = []

    for line_number, line in enumerate(
        reader.read_closer.read().splitlines(),
        1,
    ):
        if matched := MIX_LOCK_DEP.match(line.replace(" ", "")):
            pkg_name = matched.group("dep")
            pkg_version = matched.group("info").split(",")[2].strip('"')
            location = build_location(reader, line_number)

            packages.append(
                Package(
                    name=pkg_name,
                    version=pkg_version,
                    type=PackageType.HexPkg,
                    locations=[location],
                    p_url=package_url(pkg_name, pkg_version),
                    metadata=None,
                    language=Language.ELIXIR,
                    licenses=[],
                    is_dev=False,
                ),
            )

    return packages, relationships
