"""Tests for aablocks.config module."""

from __future__ import annotations

import json
import os
import stat
from pathlib import Path

import pytest

from aablocks.config import (
    get_api_format,
    get_api_verbose,
    get_auth_domain,
    get_banners_enabled,
    get_base_url,
    get_cli_format,
    get_cli_verbose,
    get_client_id,
    get_config,
    get_pool_id,
    get_progress,
    set_config,
    write_secure_file,
)


class TestGetConfig:
    def test_returns_empty_dict_when_no_file(self, tmp_aab_dir: Path):
        """Returns an empty dict when config.json does not exist."""
        assert get_config() == {}

    def test_loads_from_file(self, write_config):
        """Reads and parses an existing config.json file."""
        write_config({"api_format": "polars", "progress": False})
        config = get_config()
        assert config["api_format"] == "polars"
        assert config["progress"] is False


class TestSetConfig:
    def test_creates_file_and_writes(self, tmp_aab_dir: Path):
        """Creates config.json if it doesn't exist and writes the key."""
        set_config("api_format", "csv")
        config = get_config()
        assert config["api_format"] == "csv"

    def test_updates_existing_key(self, write_config):
        """Overwrites an existing key with the new value."""
        write_config({"api_format": "csv"})
        set_config("api_format", "polars")
        assert get_config()["api_format"] == "polars"

    def test_adds_new_key_preserves_existing(self, write_config):
        """Adding a new key does not disturb other existing keys."""
        write_config({"api_format": "csv"})
        set_config("progress", False)
        config = get_config()
        assert config["api_format"] == "csv"
        assert config["progress"] is False


class TestWriteSecureFile:
    def test_creates_parent_dirs(self, tmp_path: Path):
        """Creates intermediate parent directories when they don't exist."""
        nested = tmp_path / "a" / "b" / "file.json"
        write_secure_file(nested, {"key": "value"})
        assert nested.exists()
        assert json.loads(nested.read_text()) == {"key": "value"}

    @pytest.mark.skipif(os.name == "nt", reason="Unix permissions test")
    def test_file_permissions_0600(self, tmp_path: Path):
        """Files are created with owner-only read/write (0600) on Unix."""
        target = tmp_path / "secret.json"
        write_secure_file(target, {"token": "abc"})
        mode = stat.S_IMODE(target.stat().st_mode)
        assert mode == 0o600


class TestDefaultGetters:
    def test_api_format_default(self, tmp_aab_dir: Path):
        """Default api_format is 'pandas' when no config exists."""
        assert get_api_format() == "pandas"

    def test_cli_format_default(self, tmp_aab_dir: Path):
        """Default cli_format is 'csv' when no config exists."""
        assert get_cli_format() == "csv"

    def test_progress_default(self, tmp_aab_dir: Path):
        """Default progress is True when no config exists."""
        assert get_progress() is True

    def test_cli_verbose_default(self, tmp_aab_dir: Path):
        """Default cli_verbose is False when no config exists."""
        assert get_cli_verbose() is False

    def test_api_verbose_default(self, tmp_aab_dir: Path):
        """Default api_verbose is False when no config exists."""
        assert get_api_verbose() is False

    def test_banners_default(self, tmp_aab_dir: Path):
        """Default banners is True when no config exists."""
        assert get_banners_enabled() is True

    def test_base_url_default(self, tmp_aab_dir: Path):
        """Default base_url points to the production API."""
        assert get_base_url() == "https://api.atlas.aalphabio.com/api/v1"

    def test_auth_domain_default(self, tmp_aab_dir: Path):
        """Default auth_domain points to production."""
        assert get_auth_domain() == "auth.atlas.aalphabio.com"

    def test_pool_id_default(self, tmp_aab_dir: Path):
        """Default pool_id points to production."""
        assert get_pool_id() == "us-east-2_18ZA7hgrh"

    def test_client_id_default(self, tmp_aab_dir: Path):
        """Default client_id points to production."""
        assert get_client_id() == "7vh1h6kfah3qf9inb4q79bfl0c"


class TestCustomGetters:
    def test_api_format_custom(self, write_config):
        """Returns a user-configured api_format value."""
        write_config({"api_format": "polars"})
        assert get_api_format() == "polars"

    def test_cli_format_custom(self, write_config):
        """Returns a user-configured cli_format value."""
        write_config({"cli_format": "table"})
        assert get_cli_format() == "table"

    def test_progress_custom(self, write_config):
        """Returns a user-configured progress value."""
        write_config({"progress": False})
        assert get_progress() is False

    def test_base_url_custom(self, write_config):
        """Returns a user-configured base_url value."""
        write_config({"base_url": "https://data-api-test.aalphabio.tools/api/v1"})
        assert get_base_url() == "https://data-api-test.aalphabio.tools/api/v1"

    def test_cli_verbose_custom(self, write_config):
        """Returns a user-configured cli_verbose value."""
        write_config({"cli_verbose": True})
        assert get_cli_verbose() is True

    def test_api_verbose_custom(self, write_config):
        """Returns a user-configured api_verbose value."""
        write_config({"api_verbose": True})
        assert get_api_verbose() is True

    def test_banners_custom(self, write_config):
        """Returns a user-configured banners value."""
        write_config({"banners": False})
        assert get_banners_enabled() is False
