import json

import pytest

from mnemosynecore.vault import univ_conn


def _base_cfg(extra='{"basepath":"/custom"}'):
    return json.dumps(
        {
            "host": "localhost",
            "password": "pwd",
            "login": "usr",
            "port": 5433,
            "schema": "db",
            "extra": extra,
        }
    )


def test_un_conn_returns_engine_for_vertica(monkeypatch):
    captured = {}
    monkeypatch.setattr(univ_conn, "get_connection_as_json", lambda _: _base_cfg())
    monkeypatch.setattr(univ_conn, "create_engine", lambda url, pool_pre_ping=True: {"url": url, "pool_pre_ping": pool_pre_ping})
    engine = univ_conn.un_conn("CID", "vertica")
    assert "vertica+vertica_python://usr:pwd@localhost:5433/db" == engine["url"]
    assert engine["pool_pre_ping"] is True


def test_un_conn_supports_vertica_engine_alias(monkeypatch):
    monkeypatch.setattr(univ_conn, "get_connection_as_json", lambda _: _base_cfg())
    monkeypatch.setattr(univ_conn, "create_engine", lambda url, pool_pre_ping=True: "ENGINE")
    assert univ_conn.un_conn("CID", "vertica_engine") == "ENGINE"


def test_un_conn_clickhouse(monkeypatch):
    class FakeClient:
        def __init__(self, **kwargs):
            self.kwargs = kwargs

    monkeypatch.setattr(univ_conn, "get_connection_as_json", lambda _: _base_cfg(extra='{"secure": true}'))
    monkeypatch.setitem(__import__("sys").modules, "clickhouse_driver", type("M", (), {"Client": FakeClient})())
    client = univ_conn.un_conn("CID", "clickhouse")
    assert client.kwargs["database"] == "db"
    assert client.kwargs["secure"] is True


def test_un_conn_superset_parses_extra(monkeypatch):
    monkeypatch.setattr(univ_conn, "get_connection_as_json", lambda _: _base_cfg(extra='{"client_secret":"x"}'))
    cfg = univ_conn.un_conn("CID", "superset")
    assert cfg["host"] == "localhost"
    assert cfg["extra"]["client_secret"] == "x"


def test_un_conn_mattermost_uses_basepath(monkeypatch):
    class FakeDriver:
        def __init__(self, cfg):
            self.cfg = cfg
            self.logged_in = False

        def login(self):
            self.logged_in = True

    monkeypatch.setattr(univ_conn, "get_connection_as_json", lambda _: _base_cfg(extra='{"basepath":"/api/custom"}'))
    monkeypatch.setattr(univ_conn, "Driver", FakeDriver)
    driver = univ_conn.un_conn("CID", "mattermost")
    assert driver.cfg["basepath"] == "/api/custom"
    assert driver.logged_in is True


def test_un_conn_raw(monkeypatch):
    monkeypatch.setattr(univ_conn, "get_connection_as_json", lambda _: _base_cfg())
    cfg = univ_conn.un_conn("CID", "raw")
    assert cfg["login"] == "usr"


def test_un_conn_unknown_type(monkeypatch):
    monkeypatch.setattr(univ_conn, "get_connection_as_json", lambda _: _base_cfg())
    with pytest.raises(ValueError, match="Неизвестный conn_type"):
        univ_conn.un_conn("CID", "oops")


def test_un_conn_test_uses_test_secret(monkeypatch):
    monkeypatch.setattr(univ_conn, "get_connection_as_json_test", lambda *args, **kwargs: _base_cfg())
    monkeypatch.setattr(univ_conn, "create_engine", lambda url, pool_pre_ping=True: {"url": url})
    engine = univ_conn.un_conn_test("CID", "vertica", creds_path="/tmp/cid.json")
    assert "vertica+vertica_python://" in engine["url"]


def test_un_conn_vertica_supports_user_field(monkeypatch):
    payload = json.dumps(
        {
            "host": "localhost",
            "password": "pwd",
            "user": "usr_user",
            "port": 5433,
            "schema": "db",
            "extra": "{}",
        }
    )
    monkeypatch.setattr(univ_conn, "get_connection_as_json", lambda _: payload)
    monkeypatch.setattr(univ_conn, "create_engine", lambda url, pool_pre_ping=True: {"url": url})
    engine = univ_conn.un_conn("CID", "vertica")
    assert "usr_user:pwd@localhost:5433/db" in engine["url"]
