import kikimr.public.sdk.python.persqueue.auth as auth
import kikimr.public.sdk.python.persqueue.grpc_pq_streaming_api as pqlib
from kikimr.public.sdk.python.persqueue.errors import SessionFailureResult
from tvm2.sync.thread_tvm2 import TVM2 as TVM2Thread

from intranet.domenator.src.settings import config


class LogbrokerClient:
    def __init__(self, source_id: bytes):
        tvm_client = TVM2Thread(
            client_id=config.tvm2_client,
            secret=config.tvm2_secret.get_secret_value(),
            blackbox_client=config.tvm2_blackbox_client,
            allowed_clients=config.tvm2_allowed_clients,
        )
        self.api = pqlib.PQStreamingAPI(
            config.logbroker_write_endpoint, config.logbroker_port)
        api_start_future = self.api.start()
        api_start_future.result(timeout=10)

        credentials_provider = auth.TVMCredentialsProvider(
            tvm_client,
            destination_client_id=config.logbroker_tvm2_client,
        )

        configurator = pqlib.ProducerConfigurator(
            config.logbroker_topic, source_id)

        self.producer = self.api.create_producer(
            configurator, credentials_provider=credentials_provider)
        start_future = self.producer.start()
        start_result = start_future.result(timeout=10)

        if not isinstance(start_result, SessionFailureResult):
            if start_result.HasField("init"):
                self.max_seq_no = start_result.init.max_seq_no
            else:
                raise RuntimeError(
                    "Unexpected producer start result from server: {}.".format(start_result))
        else:
            raise RuntimeError(
                "Error occurred on start of producer: {}.".format(start_result))

    def write(self, message: bytes):
        self.max_seq_no += 1
        response = self.producer.write(self.max_seq_no, message)
        write_result = response.result(timeout=10)
        if not write_result.HasField("ack"):
            raise RuntimeError(
                "Message write failed with error {}".format(write_result))

    def shutdown(self):
        self.producer.stop()
        self.api.stop()


_instance = None


def get_client():
    global _instance
    if _instance is None:
        source_id = 'DomenatorWriter_' + config.deploy_pod_id
        _instance = LogbrokerClient(source_id.encode())
    return _instance
