# Copyright (c) 2025, NVIDIA CORPORATION.
# SPDX-License-Identifier: BSD-3-Clause

import configparser
import os
import shutil
from pathlib import Path
from typing import Dict, Optional

from megatron.energon.edataclass import edataclass


@edataclass
class ConfigEntry:
    name: str
    type: str
    provider: Optional[str]
    access_key_id: Optional[str]
    secret_access_key: Optional[str]
    region: Optional[str]
    endpoint: Optional[str]


def find_executable_path(executable_name):
    """Find the path of an executable in the PATH environment variable. Returns None if not found."""

    executable_path = shutil.which(executable_name)
    if executable_path:
        return Path(executable_path)
    return None


def get_rclone_config_path() -> Optional[Path]:
    # First check if rclone executable is in PATH, if yes, check if rclone.conf is in the same directory
    rclone_exe_path = find_executable_path("rclone")
    if rclone_exe_path is not None and rclone_exe_path.is_file():
        rclone_config_path = rclone_exe_path.with_name("rclone.conf")
        if rclone_config_path.is_file():
            return rclone_config_path

    # As a second option check the XDG_CONFIG_HOME environment variable, if it is set, check for rclone/rclone.conf in that directory
    xdg_config_home = os.environ.get("XDG_CONFIG_HOME")
    if xdg_config_home and Path(xdg_config_home).is_dir():
        rclone_config_path = Path(xdg_config_home) / "rclone" / "rclone.conf"
        if rclone_config_path.is_file():
            return rclone_config_path

    # As a third option check the default location ~/.config/rclone/rclone.conf
    rclone_config_path = Path.home() / ".config" / "rclone" / "rclone.conf"
    if rclone_config_path.is_file():
        return rclone_config_path

    # Last option is to check the legacy location ~/.rclone.conf
    legacy_config_path = Path.home() / ".rclone.conf"
    if legacy_config_path.is_file():
        return legacy_config_path

    return None


def read_rclone_config_at_path(config_path: Path) -> Dict[str, ConfigEntry]:
    """Reads the config file and returns a dictionary with the config entries."""

    config = configparser.ConfigParser()
    config.read(config_path)

    config_entries = {}
    for section in config.sections():
        entry = ConfigEntry(
            name=section,
            type=config[section].get("type"),
            provider=config[section].get("provider"),
            access_key_id=config[section].get("access_key_id"),
            secret_access_key=config[section].get("secret_access_key"),
            region=config[section].get("region"),
            endpoint=config[section].get("endpoint"),
        )
        config_entries[section] = entry

    return config_entries


def read_rclone_config() -> Dict[str, ConfigEntry]:
    config_path = get_rclone_config_path()
    if config_path is None:
        raise FileNotFoundError("Could not find rclone configuration file.")
    return read_rclone_config_at_path(config_path)
