import os
import pytest
import tomlkit

from wurker.settings import conf, get_conf
from wurker.hive import Hive
from wurker.core import Wurkman
from wurker.bee import Bee, PyBee


@pytest.fixture
def app_root():
    return os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


@pytest.fixture
def etc_root():
    etc_root = ''
    if os.path.isdir(os.path.abspath(os.path.expanduser("~/.config/wurker/etc"))):
        etc_root = os.path.abspath(os.path.expanduser("~/.config/wurker/etc"))

    return etc_root


@pytest.fixture
def config():
    # Use the same config file that the global conf object uses
    from wurker.settings import conf as global_conf
    import tomlkit

    config = None
    with open(global_conf.config_file, 'rb') as f:
        config = tomlkit.load(f)

    return config


def test_01_wurkertoml_exists(etc_root):
    toml_path = os.path.join(etc_root, "wurker.toml")
    assert os.path.exists(toml_path)


def test_02_settings(app_root, etc_root, config):
    assert conf.app_root == app_root
    assert conf.etc_root == etc_root

    assert "wurker" in config
    wurker = config["wurker"]

    assert conf.name == wurker["name"]
    assert conf.app_id == wurker["app_id"]
    assert conf.env == wurker["env"]
    assert conf.log == wurker["log"]
    assert conf.loglevel == wurker["loglevel"]
    assert conf.is_queen == wurker["is_queen"]
    assert conf.debug == wurker["debug"]

    assert "ui" in config
    ui = config["ui"]

    assert conf.domain == ui["domain"]
    assert conf.workers == ui["workers"]

    assert "local_db" in config
    local_db = config["local_db"]

    assert conf.local_db.hostname == local_db["hostname"]
    assert conf.local_db.username == local_db["username"]
    assert conf.local_db.password == local_db["password"]
    assert os.path.basename(conf.local_db.database) == local_db["database"]
    assert conf.local_db.dbdriver == local_db["dbdriver"]
    assert conf.local_db.port == local_db["port"]

    assert "remote_db" in config
    remote_db = config["remote_db"]

    assert conf.remote_db.hostname == remote_db["hostname"]
    assert conf.remote_db.username == remote_db["username"]
    assert conf.remote_db.password == remote_db["password"]
    assert os.path.basename(conf.remote_db.database) == remote_db["database"]
    assert conf.remote_db.dbdriver == remote_db["dbdriver"]
    assert conf.remote_db.port == remote_db["port"]


def test_03_init_wurkman(app_root):
    wurkman = Wurkman()

    assert wurkman.app_id == conf.app_id
    assert wurkman.app_root == conf.app_root
    assert wurkman.db_conf == conf.RemoteDB
    assert wurkman.session is not None
    assert isinstance(wurkman.hive, Hive)

    assert wurkman.slug_map is not None
    assert "bee" in wurkman.slug_map
    assert wurkman.slug_map["bee"] is not None
    assert "cron" in wurkman.slug_map
    assert wurkman.slug_map["cron"] is not None


def test_04_get_bees(app_root):
    wurkman = Wurkman()

    bees, _ = wurkman.get_bees()
    for wurk_type, wurk_data in bees.items():
        for cron_slug, cron_data in wurk_data.items():
            for bee_slug, bee_data in cron_data.items():
                assert isinstance(bee_data, Bee) or isinstance(bee_data, PyBee)


def test_05_get_hive(app_root):
    wurkman = Wurkman()

    hive = wurkman.get_hive()
    assert len(hive) == 0


def test_06_get_control(app_root):
    wurkman = Wurkman()

    control = wurkman.get_control()
    assert control is not None


def test_07_set_control(app_root):
    wurkman = Wurkman()

    wurkman.set_control(reload=True)
    control = wurkman.get_control()
    assert control.reload == True

    wurkman.set_control(reload=False)

    wurkman.set_control(pause=True)
    control = wurkman.get_control()
    assert control.pause == True

    wurkman.set_control(pause=False)


def test_08_remote_sqlite_defaults(monkeypatch, tmp_path):
    import wurker.settings as settings_mod

    conf_root = tmp_path / "wurker-conf"
    etc_root = conf_root / "etc"
    etc_root.mkdir(parents=True)

    toml_path = etc_root / "wurker.toml"
    toml_path.write_text(
        """
[wurker]
name = "Wurker"
app_id = "6b018c2b-77b7-40ca-bb82-cc8378252f67"
env = "local"
log = "stderr"
loglevel = "debug"
is_queen = true
debug = false

[ui]
domain = ""
workers = 3

[local_db]
hostname = ""
username = ""
password = ""
database = "wurker.db"
dbdriver = "sqlite"
port = 0

[remote_db]
hostname = ""
username = ""
password = ""
database = ""
dbdriver = "sqlite"
port = 0
""".lstrip()
    )

    monkeypatch.setenv("WURKER_CONFIG_DIR", str(conf_root))

    old_conf = settings_mod._conf
    settings_mod._conf = None
    try:
        conf = get_conf()
        assert os.path.basename(conf.RemoteDB.database) == "wurker-remote.db"
        assert conf.RemoteDB.url.endswith("wurker-remote.db")

        # With explicit remote default set, it should override local.
        assert conf.RemoteDB.dbdriver == "sqlite"
    finally:
        settings_mod._conf = old_conf
        monkeypatch.delenv("WURKER_CONFIG_DIR", raising=False)
