import asyncio
import time

import aiohttp

from clarabot_nano.common.i18n import DETECTED_SYSTEM_LANGUAGE
from clarabot_nano.common.solr.api import is_solr_core_available, SolrApiError
from clarabot_nano.common.solr.rest import (
    nano_query_get,
    nano_update_post,
    preparse_solr_response,
    extract_query_response,
)

SOLR_LOCALE_LANGS = sorted({"en"} | {DETECTED_SYSTEM_LANGUAGE if DETECTED_SYSTEM_LANGUAGE else "en"})
SOLR_ALL_LANGS = sorted(["en", "hu"])


def assert_solr_query_result(q, docs, num, start=0, exact=True):
    q = dict(q)
    q.pop("time")
    r = {"numFound": num, "start": start, "docs": docs}
    if exact is None:
        q.pop("numFoundExact", None)
    else:
        r["numFoundExact"] = exact
    assert q == r, f"solr query mismatch:\n{q}\n{r}"


async def run_check_query(session, q_url, auth_header, query_args, *args, return_paths=False, **kwargs):
    async with nano_query_get(session, q_url, auth_header, query_args) as r_:
        q_, s_ = await preparse_solr_response(r_)
        assert s_, f"{q_}"
        q = extract_query_response(q_)
        if return_paths:
            return [d["path"] for d in q["docs"]]
        assert_solr_query_result(q, *args, **kwargs)


async def run_check_update(session, u_url, auth_header, docs_, success=True, commit=True, soft_commit=False):
    async with nano_update_post(session, u_url, auth_header, docs_, commit=commit, soft_commit=soft_commit) as r_:
        q_, s_ = await preparse_solr_response(r_)
        assert s_ is success, str(q_)
        return q_


async def wait_solr_startup(session, port, auth_h, core_name=None, timeout=16.0):
    timeout += time.perf_counter()
    while True:
        try:
            available = await is_solr_core_available(session, port, auth_h, core_name)
            if core_name is not None and not available:
                raise SolrApiError("Not available")
            break
        except (aiohttp.ClientError, SolrApiError):
            if time.perf_counter() > timeout:
                raise
            await asyncio.sleep(0.75)


def mutate_remote_config_indexed_languages(value, c):
    assert "indexed_languages" in c
    c["indexed_languages"] = value
