"""Configuration management for pypack."""

from __future__ import annotations

import argparse
from dataclasses import dataclass
from enum import Enum
from functools import cached_property
from pathlib import Path


class LoaderType(Enum):
    """Enumeration of supported loader types."""

    CONSOLE = "console"
    GUI = "gui"


class ArchiveFormat(Enum):
    """Enumeration of supported archive formats."""

    ZIP = "zip"
    SEVEN_ZIP = "7z"
    NSIS = "nsis"


class MirrorSource(Enum):
    """Enumeration of supported PyPI mirror sources."""

    PYPI = "pypi"
    TSINGHUA = "tsinghua"
    ALIYUN = "aliyun"
    USTC = "ustc"
    DOUBAN = "douban"
    TENCENT = "tencent"


@dataclass
class WorkflowConfig:
    """Configuration for package workflow with type-safe enums."""

    directory: Path
    project_name: str | None = None
    python_version: str = "3.8.10"
    loader_type: LoaderType = LoaderType.CONSOLE
    entry_suffix: str = ".ent"
    generate_loader: bool = True
    offline: bool = False
    max_concurrent: int = 4
    debug: bool = False
    cache_dir: Path | None = None
    archive_format: ArchiveFormat = ArchiveFormat.ZIP
    mirror: MirrorSource = MirrorSource.ALIYUN
    archive_type: str | None = None

    @cached_property
    def normalized_directory(self) -> Path:
        """Get normalized and resolved directory path."""
        return self.directory.resolve()

    @cached_property
    def dist_dir(self) -> Path:
        """Get distribution directory path."""
        return self.normalized_directory / "dist"

    @cached_property
    def build_dir(self) -> Path:
        """Get build directory path."""
        return self.normalized_directory / "build"


class ConfigFactory:
    """Factory for creating workflow configurations with validation."""

    @staticmethod
    def create_from_args(args: argparse.Namespace, cwd: Path) -> WorkflowConfig:
        """Create configuration from command line arguments."""
        # For commands that don't need project-specific config, use defaults
        project_name = getattr(args, "project", None)

        return WorkflowConfig(
            directory=cwd,
            project_name=project_name,
            python_version=getattr(args, "python_version", "3.8.10"),
            loader_type=LoaderType(getattr(args, "loader_type", "console")),
            entry_suffix=getattr(args, "entry_suffix", ".ent"),
            generate_loader=not getattr(args, "no_loader", False),
            offline=getattr(args, "offline", False),
            max_concurrent=getattr(args, "jobs", 4),
            debug=getattr(args, "debug", False),
            cache_dir=Path(args.cache_dir) if getattr(args, "cache_dir", None) else None,
            archive_format=ArchiveFormat(getattr(args, "archive_format", "zip")),
            mirror=MirrorSource(getattr(args, "mirror", "aliyun")),
            archive_type=getattr(args, "archive", None),
        )

    @staticmethod
    def create_default(directory: Path) -> WorkflowConfig:
        """Create default configuration."""
        return WorkflowConfig(directory=directory)
