import pytest

from clarabot_nano.common.solr.rest import (
    create_solr_core_url,
    create_nano_schema_url,
    create_nano_query_url,
    quote_escape,
    get_solr_error,
    check_solr_error,
    preparse_solr_response,
    serialize_solr_update_json,
)


def test_solr_create_solr_core_url():
    assert create_solr_core_url("X0Y", 321, "X2Y", "X3Y") == "http://X0Y:321/solr/X2Y/X3Y"


def test_solr_create_nano_schema_url():
    assert create_nano_schema_url(321, "nano_core") == "http://127.0.0.1:321/solr/nano_core/schema"


def test_solr_create_nano_query_url():
    assert create_nano_query_url(321, "nano_core") == "http://127.0.0.1:321/solr/nano_core/query"


def test_solr_quote_escape():
    assert quote_escape("asd") == "asd"
    assert quote_escape("\\asd") == "\\\\asd"
    assert quote_escape('"asd') == '\\"asd'
    assert quote_escape('\\"asd') == '\\\\\\"asd'
    assert quote_escape("\\\\") == "\\\\\\\\"
    assert quote_escape('""') == '\\"\\"'


def test_get_solr_error():
    for t in [None, b"xxx", "<html></thml>", b"{}"]:
        assert get_solr_error(t) is None
    assert get_solr_error(b'{"error":{}}') == (None, None)
    assert get_solr_error(b'{"error":{"code":55}}') == (55, None)
    assert get_solr_error(b'{"error":{"msg":"me"}}') == (None, "me")
    assert get_solr_error(b'{"error":{"code":55,"msg":"me"}}') == (55, "me")


def test_check_solr_error():
    for t in [None, b"xxx", "<html></thml>", b"{}"]:
        assert check_solr_error(t) is False
    assert check_solr_error(b'{"error":{}}') is True
    assert check_solr_error(b'{"error":{}}', 55) is False
    assert check_solr_error(b'{"error":{}}', None, "me") is False
    assert check_solr_error(b'{"error":{}}', 55, "me") is False
    assert check_solr_error(b'{"error":{"code":55}}', 55) is True
    assert check_solr_error(b'{"error":{"msg":"it\' me, yes"}}', None, "me") is True
    assert check_solr_error(b'{"error":{"code":55, "msg":"it\' me, yes"}}', 55, "me") is True


@pytest.mark.asyncio
async def test_preparse_solr_response():
    class _TestingResponse(object):
        def __init__(self, s: int, x=None):
            self.status = s
            self.x = x

        async def read(self):
            return self.x

    assert await preparse_solr_response(_TestingResponse(400, b"x1")) == (b"x1", False)
    assert await preparse_solr_response(_TestingResponse(200, b"x1")) == (b"x1", False)
    assert await preparse_solr_response(_TestingResponse(200, b"{}")) == ({}, False)
    assert await preparse_solr_response(_TestingResponse(200, b'{"responseHeader":{"status":1}}')) == (
        {"responseHeader": {"status": 1}},
        False,
    )
    assert await preparse_solr_response(_TestingResponse(200, b'{"responseHeader":{"status":0}}')) == (
        {"responseHeader": {"status": 0}},
        True,
    )


def test_serialize_solr_update_json():
    assert serialize_solr_update_json([]) == b"{}"
    assert serialize_solr_update_json([("add", {"id": 1})]) == b'{"add":{"doc":{"id":1}}}'
    assert serialize_solr_update_json([("delete", {"id": 1})]) == b'{"delete":{"id":1}}'
    assert serialize_solr_update_json([("add", {"doc": {"id": 1}})]) == b'{"add":{"doc":{"id":1}}}'
    assert (
        serialize_solr_update_json([("add", {"doc": {"id": 1}, "overwrite": False})])
        == b'{"add":{"doc":{"id":1},"overwrite":false}}'
    )
    assert (
        serialize_solr_update_json([("add", {"id": 1}), ("add", {"id": 2})])
        == b'{"add":{"doc":{"id":1}},"add":{"doc":{"id":2}}}'
    )
