from __future__ import annotations

from pathlib import Path

import pytest

from app.core import install_secrets as secrets


@pytest.fixture
def secrets_dir(tmp_path: Path, monkeypatch):
    install_dir = tmp_path / "secrets"
    install_file = install_dir / "install.env"
    meta_file = install_dir / "install.meta.json"
    monkeypatch.setattr(secrets, "INSTALL_SECRETS_DIR", install_dir)
    monkeypatch.setattr(secrets, "INSTALL_SECRETS_FILE", install_file)
    monkeypatch.setattr(secrets, "INSTALL_SECRETS_META_FILE", meta_file)
    return install_dir, install_file, meta_file


def test_read_install_secrets_empty_when_missing(secrets_dir):
    _, install_file, _ = secrets_dir
    assert not install_file.exists()
    assert secrets.read_install_secrets() == {}


def test_write_and_read_install_secrets_roundtrip(secrets_dir):
    install_dir, install_file, _ = secrets_dir
    install_dir.mkdir(parents=True, exist_ok=True)
    install_file.write_text(
        "JWT_ACCESS_SECRET=abc\n# comment\nPOSTGRES_PASSWORD=secret\n",
        encoding="utf-8",
    )
    values = secrets.read_install_secrets()
    assert values["JWT_ACCESS_SECRET"] == "abc"
    assert values["POSTGRES_PASSWORD"] == "secret"


def test_sync_minio_s3_secrets_aligns_keys():
    values = {
        "S3_ACCESS_KEY": "minio",
        "MINIO_ROOT_USER": "minio",
        "MINIO_ROOT_PASSWORD": "root-secret",
        "S3_SECRET_KEY": "old-secret",
    }
    synced = secrets._sync_minio_s3_secrets(values)
    assert synced["S3_SECRET_KEY"] == "root-secret"


def test_masked_database_url_hides_password():
    masked = secrets.masked_database_url("postgresql://user:pass@localhost:5432/compton")
    assert "pass" not in masked
    assert "user:***" in masked


def test_install_secrets_payload_reports_status(secrets_dir):
    install_dir, install_file, _ = secrets_dir
    install_dir.mkdir(parents=True, exist_ok=True)
    install_file.write_text(
        "\n".join(
            [
                "SECRETS_LOCKED=true",
                "DATABASE_URL=postgresql://compton_app:secret@postgres:5432/compton",
                "JWT_ACCESS_SECRET=abc",
                "JWT_REFRESH_PEPPER=def",
                "POSTGRES_PASSWORD=secret",
                "S3_SECRET_KEY=key",
            ]
        )
        + "\n",
        encoding="utf-8",
    )
    payload = secrets.install_secrets_payload()
    assert payload["initialized"] is True
    assert payload["locked"] is True
    assert payload["database"]["user"] == "compton_app"
    assert "***" in payload["connection_string_masked"]


def test_reveal_install_secret_supported_and_unsupported(secrets_dir):
    install_dir, install_file, _ = secrets_dir
    install_dir.mkdir(parents=True, exist_ok=True)
    install_file.write_text("JWT_ACCESS_SECRET=top-secret\n", encoding="utf-8")
    assert secrets.reveal_install_secret("jwt_access_secret") == "top-secret"
    with pytest.raises(ValueError, match="UNSUPPORTED_SECRET_KEY"):
        secrets.reveal_install_secret("unknown")


def test_ensure_install_secrets_creates_locked_bundle(secrets_dir, monkeypatch):
    install_dir, install_file, meta_file = secrets_dir
    monkeypatch.delenv("DATABASE_URL", raising=False)
    status = secrets.ensure_install_secrets()
    assert status.created is True
    assert status.locked is True
    assert install_file.exists()
    assert meta_file.exists()
    values = secrets.read_install_secrets()
    assert values["SECRETS_LOCKED"] == "true"
    assert values["JWT_ACCESS_SECRET"]


def test_ensure_install_secrets_adopts_existing_locked_file(secrets_dir):
    install_dir, install_file, meta_file = secrets_dir
    install_dir.mkdir(parents=True, exist_ok=True)
    install_file.write_text(
        "SECRETS_LOCKED=true\nJWT_ACCESS_SECRET=existing\nJWT_REFRESH_PEPPER=pepper\n"
        "POSTGRES_PASSWORD=pw\nPOSTGRES_USER=u\nPOSTGRES_DB=db\nDATABASE_URL=postgresql://u:pw@localhost/db\n"
        "S3_ACCESS_KEY=a\nS3_SECRET_KEY=b\nMINIO_ROOT_USER=a\nMINIO_ROOT_PASSWORD=b\n",
        encoding="utf-8",
    )
    meta_file.write_text('{"install_id":"x","locked_at":"2026-01-01T00:00:00+00:00"}\n', encoding="utf-8")
    status = secrets.ensure_install_secrets()
    assert status.created is False
    assert status.locked is True
    assert secrets.read_install_secrets()["JWT_ACCESS_SECRET"] == "existing"
