import pytest

from credmgr.exceptions import Conflict, NotFound
from credmgr.models import Bot


def assert_created(bot, data):
    for key, value in data.items():
        if key in ["reddit_app", "sentry_token", "database_credential", "owner"]:
            assert getattr(bot, key).id == value
            continue
        assert getattr(bot, key) == value


def test_create_bot(recorder, credential_manager):
    data = {"name": "bot_name"}
    bot = credential_manager.bot.create(**data)
    assert_created(bot, data)


def test_create_bot_full_params(recorder, credential_manager):
    data = {
        "name": "bot_name_2",
        "reddit_app": 27,
        "sentry_token": 4,
        "database_credential": 1,
    }
    bot = credential_manager.bot.create(**data)
    assert_created(bot, data)


def test_create_bot_full_params_objects(recorder, credential_manager):
    data = {
        "name": "bot_name_2",
        "reddit_app": credential_manager.reddit_app(27),
        "sentry_token": credential_manager.sentry_token(4),
        "database_credential": credential_manager.database_credential(1),
    }
    bot = credential_manager.bot.create(**data)
    for key, value in data.items():
        assert getattr(bot, key) == value


def test_create_bot_other_user(recorder, credential_manager):
    data = {
        "name": "bot_name_3",
        "reddit_app": 29,
        "sentry_token": 12,
        "database_credential": 20,
        "owner": 4,
    }
    bot = credential_manager.bot.create(**data)
    assert_created(bot, data)


def test_create_bot_existing(recorder, credential_manager):
    data = {"name": "bot_name", "reddit_app": 27}
    with pytest.raises(Conflict):
        _ = credential_manager.bot.create(**data)


def test_delete_bot(recorder, credential_manager):
    bot = credential_manager.bot("bot_name")
    bot.delete()
    with pytest.raises(NotFound):
        _ = credential_manager.bot("bot_name")


def test_edit_bot(recorder, credential_manager):
    bot = credential_manager.bot("bot_name_2")
    bot.edit(reddit_app=28, name="new_bot_name")
    assert bot.reddit_app.id == 28
    assert bot.name == "new_bot_name"


def test_edit_bot_with_object(recorder, credential_manager):
    bot = credential_manager.bot("bot_name4")
    bot.edit(reddit_app=credential_manager.reddit_app(28))
    assert bot.reddit_app.id == 28


def test_edit_bot_conflicting_data(recorder, credential_manager):
    bot = credential_manager.bot("new_bot_name")
    with pytest.raises(Conflict):
        bot.edit(name="bot_name4")


def test_list_bots(recorder, credential_manager):
    bots = credential_manager.bots()
    for bot in bots:
        assert isinstance(bot, Bot)
