# ///////////////////////////////////////////////////////////////
# EZPL - Environment Variable Manager
# Project: ezpl
# ///////////////////////////////////////////////////////////////

"""
Environment variable manager for CLI operations.

This module provides functionality to manage user environment variables
for Ezpl configuration.
"""

from __future__ import annotations

# ///////////////////////////////////////////////////////////////
# IMPORTS
# ///////////////////////////////////////////////////////////////
# Standard library imports
import os
import sys
from pathlib import Path

# ///////////////////////////////////////////////////////////////
# CLASSES
# ///////////////////////////////////////////////////////////////


class UserEnvManager:
    """
    Manager for user environment variables.

    Manages environment variables in user profile for Ezpl configuration.
    """

    # Mapping of configuration keys to environment variable names
    CONFIG_TO_ENV = {
        "log-level": "EZPL_LOG_LEVEL",
        "log-file": "EZPL_LOG_FILE",
        "log-dir": "EZPL_LOG_DIR",
        "printer-level": "EZPL_PRINTER_LEVEL",
        "indent-step": "EZPL_INDENT_STEP",
        "indent-symbol": "EZPL_INDENT_SYMBOL",
        "base-indent-symbol": "EZPL_BASE_INDENT_SYMBOL",
        "file-logger-level": "EZPL_FILE_LOGGER_LEVEL",
        "log-format": "EZPL_LOG_FORMAT",
        "log-rotation": "EZPL_LOG_ROTATION",
        "log-retention": "EZPL_LOG_RETENTION",
        "log-compression": "EZPL_LOG_COMPRESSION",
    }

    # ///////////////////////////////////////////////////////////////
    # INIT
    # ///////////////////////////////////////////////////////////////

    def __init__(self) -> None:
        """Initialize the environment variable manager."""
        self.env_file = self._get_env_file_path()
        self._tracked_vars: list[str] = []

    # ------------------------------------------------
    # PRIVATE HELPER METHODS
    # ------------------------------------------------

    def _get_env_file_path(self) -> Path:
        """
        Get the path to the user environment file.

        Returns:
            Path to .env file in user's Ezpl directory
        """
        if sys.platform == "win32":
            # Windows: %USERPROFILE%\.ezpl\.env
            user_profile = os.getenv("USERPROFILE", str(Path.home()))
            return Path(user_profile) / ".ezpl" / ".env"
        else:
            # Linux/macOS: ~/.ezpl/.env
            return Path.home() / ".ezpl" / ".env"

    def _load_env_file(self) -> dict[str, str]:
        """
        Load environment variables from .env file.

        Returns:
            Dictionary of environment variables
        """
        env_vars = {}
        if self.env_file.exists():
            try:
                with open(self.env_file, encoding="utf-8") as f:
                    for line in f:
                        line = line.strip()
                        if line and not line.startswith("#") and "=" in line:
                            key, value = line.split("=", 1)
                            env_vars[key.strip()] = value.strip()
            except (OSError, ValueError):
                pass
        return env_vars

    def _save_env_file(self, env_vars: dict[str, str]) -> None:
        """
        Save environment variables to .env file.

        Args:
            env_vars: Dictionary of environment variables to save
        """
        self.env_file.parent.mkdir(parents=True, exist_ok=True)

        # Keep only managed variables to ensure removals are persisted
        managed_vars = {
            key: value for key, value in env_vars.items() if key.startswith("EZPL_")
        }

        # Write back
        try:
            with open(self.env_file, "w", encoding="utf-8") as f:
                f.write("# Ezpl User Environment Variables\n")
                f.write("# Generated by: ezpl config set --env\n")
                f.write("# DO NOT EDIT MANUALLY - Use 'ezpl config set --env'\n\n")
                for key, value in sorted(managed_vars.items()):
                    f.write(f"{key}={value}\n")
        except OSError:
            pass

    def _get_tracked_vars(self) -> list[str]:
        """
        Get list of tracked environment variables.

        Returns:
            List of environment variable names that Ezpl manages
        """
        if not self._tracked_vars:
            # Load from file if exists
            env_vars = self._load_env_file()
            self._tracked_vars = [key for key in env_vars if key.startswith("EZPL_")]
        return self._tracked_vars

    # ///////////////////////////////////////////////////////////////
    # PUBLIC METHODS
    # ///////////////////////////////////////////////////////////////

    def set_user_env(self, config_key: str, value: str) -> bool:
        """
        Set a user environment variable from a config key.

        Args:
            config_key: Configuration key (e.g., "log-level")
            value: Value to set

        Returns:
            True if successful, False otherwise
        """
        env_var = self.CONFIG_TO_ENV.get(config_key)
        if not env_var:
            return False

        try:
            env_vars = self._load_env_file()
            env_vars[env_var] = value
            self._save_env_file(env_vars)

            # Track this variable
            if env_var not in self._tracked_vars:
                self._tracked_vars.append(env_var)

            return True
        except (OSError, ValueError):
            return False

    def get_user_env(self, config_key: str) -> str | None:
        """
        Get a user environment variable value from a config key.

        Args:
            config_key: Configuration key (e.g., "log-level")

        Returns:
            Environment variable value or None
        """
        env_var = self.CONFIG_TO_ENV.get(config_key)
        if not env_var:
            return None

        env_vars = self._load_env_file()
        return env_vars.get(env_var)

    def remove_user_env(self, config_key: str) -> bool:
        """
        Remove a user environment variable.

        Args:
            config_key: Configuration key (e.g., "log-level")

        Returns:
            True if successful, False otherwise
        """
        env_var = self.CONFIG_TO_ENV.get(config_key)
        if not env_var:
            return False

        try:
            env_vars = self._load_env_file()
            if env_var in env_vars:
                del env_vars[env_var]
                self._save_env_file(env_vars)

            # Remove from tracked vars
            if env_var in self._tracked_vars:
                self._tracked_vars.remove(env_var)

            return True
        except (OSError, ValueError):
            return False

    def remove_all_user_env(self) -> bool:
        """
        Remove all Ezpl user environment variables.

        Returns:
            True if successful, False otherwise
        """
        try:
            env_vars = self._load_env_file()
            ezpl_vars = {k: v for k, v in env_vars.items() if k.startswith("EZPL_")}

            if not ezpl_vars:
                return True

            # Remove all EZPL_ vars
            for key in list(ezpl_vars.keys()):
                del env_vars[key]

            self._save_env_file(env_vars)
            self._tracked_vars = []

            return True
        except (OSError, ValueError):
            return False

    def list_user_env(self) -> dict[str, str]:
        """
        List all user environment variables managed by Ezpl.

        Returns:
            Dictionary mapping environment variable names to values
        """
        env_vars = self._load_env_file()
        return {k: v for k, v in env_vars.items() if k.startswith("EZPL_")}
