import asyncio
import logging
import math
import time

from saas.library.python.deploy_manager_api import SaasService

from saas.tools.devops.canary.reader.configs import AppConfig, ServiceType
from saas.tools.devops.canary.reader.core.kv_reader import KVDocReader
from saas.tools.devops.canary.reader.core.state_tracker import ReadStateTracker
from saas.tools.devops.canary.reader.core.tvm import TvmClient
from saas.tools.devops.canary.reader.core.discovery import SearchProxyDiscovery


class ReadManager:
    _SERVICE_TYPE_TO_DOC_READER_CLS = {
        ServiceType.KV: KVDocReader
    }

    def __init__(
        self,
        config: AppConfig,
        service: SaasService,
        sp_discovery: SearchProxyDiscovery,
        tvm_client: TvmClient
    ) -> None:
        self._config: AppConfig = config
        self._service: SaasService = service
        self._sp_discovery: SearchProxyDiscovery = sp_discovery
        self._tvm_client: TvmClient = tvm_client

    async def infinite_read(self) -> None:
        start_lag = self._config.read_check_start_lag
        logging.info('Waiting for the start lag (%ds) and the init of other services before continue', start_lag)

        await asyncio.gather(*[asyncio.sleep(start_lag), self._sp_discovery.first_update.wait()])

        ts = time.time()
        ts_ceil = math.ceil(ts)

        reader = self._SERVICE_TYPE_TO_DOC_READER_CLS[self._config.service_type](
            self._service,
            self._sp_discovery,
            ReadStateTracker(self._service),
            self._tvm_client
        )

        while True:
            check_ts = ts_ceil - self._config.read_check_lag
            await reader.check_document(text=str(check_ts))

            ts = time.time()
            ceil = math.ceil(ts)
            ts_ceil = ceil if ceil > ts_ceil else ceil + 1

            await asyncio.sleep(ts_ceil - ts)
