from __future__ import annotations

import subprocess
from pathlib import Path

import tomllib
from hatchling.builders.hooks.plugin.interface import BuildHookInterface
from hatchling.metadata.plugin.interface import MetadataHookInterface


class CustomMetaDataHook(MetadataHookInterface):
    """
    Custom metadata hook.
    """

    def update(self, metadata: dict[str, object]) -> None:
        """
        Update the metadata for the store package.

        Parameters
        ----------
        metadata
            The current metadata
        """
        source_path = Path(self.root, "..", "pyproject.toml")
        if source_path.exists():
            with source_path.open("rb") as f:
                source_metadata = tomllib.load(f)
                project = source_metadata["project"]
            result = subprocess.run(
                ["hatch", "version"],
                cwd=Path(self.root, ".."),
                check=True,
                capture_output=True,
                text=True,
            )
            version = result.stdout.strip()
            # Set version
            metadata["version"] = version
            # Set metadata fields
            for key in (
                "name",
                "description",
                "requires-python",
                "license",
                "authors",
                "maintainers",
                "keywords",
                "classifiers",
                "urls",
                "gui-scripts",
                "scripts",
                "entry-points",
            ):
                if key in project:
                    metadata[key] = project[key]
            # Update name
            metadata["name"] += ".store"
            # Set dependencies
            if "dependencies" in project:
                metadata["dependencies"] = [f"{project['name']}=={version}"]
            # Set optional dependencies
            if "optional-dependencies" in project:
                metadata["optional-dependencies"] = {}
                for group in project["optional-dependencies"]:
                    metadata["optional-dependencies"][group] = [
                        f"{project['name']}[{group}]=={version}",
                    ]

            # Set readme if needed
            try:
                targets = source_metadata["tool"]["hatch"]["build"]["targets"]
                readme = targets["package.store"]["metadata"]["readme"]
                metadata["readme"] = readme
                internal = Path(readme)
                external = Path("..", readme)
                if not internal.exists():
                    internal.symlink_to(external)
            except KeyError:
                pass


class CustomBuildHook(BuildHookInterface):
    """
    Custom build hook.
    """

    def initialize(
        self,
        version: str,
        build_data: dict[str, object],
    ) -> None:
        """
        Initialize the build process.

        Parameters
        ----------
        version
            The version (``standard``, ``editable``, ...)
        build_data
            The build data

        """
        if version == "standard":
            source_path = Path(self.root, "..", "pyproject.toml")
            if source_path.exists():
                with source_path.open("rb") as f:
                    source_metadata = tomllib.load(f)
                    # Set readme if needed
                    try:
                        targets = source_metadata["tool"]["hatch"]["build"]["targets"]
                        readme = targets["package.store"]["metadata"]["readme"]
                        internal = Path(readme)
                        external = Path("..", readme)
                        if not internal.exists():
                            internal.symlink_to(external)
                    except KeyError:
                        pass

    def finalize(
        self,
        version: str,
        build_data: dict[str, object],
        artifact_path: str,
    ) -> None:
        """
        Finalize the build process.

        Parameters
        ----------
        version
            The version (``standard``, ``editable``, ...)
        build_data
            The build data
        artifact_path
            The artifact path

        """
        if version == "standard":
            source_path = Path(self.root, "..", "pyproject.toml")
            if source_path.exists():
                with source_path.open("rb") as f:
                    source_metadata = tomllib.load(f)
                    # Set readme if needed
                    try:
                        targets = source_metadata["tool"]["hatch"]["build"]["targets"]
                        readme = targets["package.store"]["metadata"]["readme"]
                        internal = Path(readme)
                        internal.unlink(missing_ok=True)
                    except KeyError:
                        pass
