"""Tests for safeconfig.utils.env_writer."""

from __future__ import annotations

from pathlib import Path

import pytest

from pysafeconfigx.utils.env_writer import create_env_template, delete_key, upsert_key


class TestUpsertKey:
    def test_creates_new_file(self, tmp_path: Path) -> None:
        p = tmp_path / ".env"
        assert not p.exists()
        upsert_key(p, "FOO", "bar")
        assert p.exists()
        assert "FOO=bar" in p.read_text()

    def test_appends_new_key(self, tmp_path: Path) -> None:
        p = tmp_path / ".env"
        p.write_text("EXISTING=value\n", encoding="utf-8")
        upsert_key(p, "NEW", "newvalue")
        content = p.read_text()
        assert "EXISTING=value" in content
        assert "NEW=newvalue" in content

    def test_updates_existing_key(self, tmp_path: Path) -> None:
        p = tmp_path / ".env"
        p.write_text("KEY=old\n", encoding="utf-8")
        upsert_key(p, "KEY", "new")
        content = p.read_text()
        assert "KEY=new" in content
        assert "old" not in content

    def test_preserves_comments(self, tmp_path: Path) -> None:
        p = tmp_path / ".env"
        p.write_text("# My comment\nKEY=value\n", encoding="utf-8")
        upsert_key(p, "OTHER", "other")
        content = p.read_text()
        assert "# My comment" in content

    def test_invalid_key_raises(self, tmp_path: Path) -> None:
        p = tmp_path / ".env"
        with pytest.raises(ValueError, match="valid environment variable"):
            upsert_key(p, "123invalid", "value")

    def test_quotes_value_with_spaces(self, tmp_path: Path) -> None:
        p = tmp_path / ".env"
        upsert_key(p, "MSG", "hello world")
        content = p.read_text()
        assert 'MSG="hello world"' in content


class TestDeleteKey:
    def test_deletes_existing_key(self, tmp_path: Path) -> None:
        p = tmp_path / ".env"
        p.write_text("FOO=bar\nBAZ=qux\n", encoding="utf-8")
        removed = delete_key(p, "FOO")
        assert removed is True
        content = p.read_text()
        assert "FOO" not in content
        assert "BAZ=qux" in content

    def test_returns_false_for_missing_key(self, tmp_path: Path) -> None:
        p = tmp_path / ".env"
        p.write_text("FOO=bar\n", encoding="utf-8")
        assert delete_key(p, "MISSING") is False

    def test_returns_false_for_missing_file(self, tmp_path: Path) -> None:
        assert delete_key(tmp_path / "nonexistent.env", "KEY") is False


class TestCreateEnvTemplate:
    def test_creates_file(self, tmp_path: Path) -> None:
        p = tmp_path / ".env"
        create_env_template(p, ["KEY_A", "KEY_B"])
        content = p.read_text()
        assert "KEY_A" in content
        assert "KEY_B" in content

    def test_raises_if_exists_no_overwrite(self, tmp_path: Path) -> None:
        p = tmp_path / ".env"
        p.write_text("existing\n", encoding="utf-8")
        with pytest.raises(FileExistsError):
            create_env_template(p, ["KEY"])

    def test_overwrite_flag(self, tmp_path: Path) -> None:
        p = tmp_path / ".env"
        p.write_text("old content\n", encoding="utf-8")
        create_env_template(p, ["NEW_KEY"], overwrite=True)
        content = p.read_text()
        assert "NEW_KEY" in content
