import json
import logging
import logging.config
import os

import cfgtools
from helper import import_pydevd
from mbcontextmessagehandler import (
    MbContextMessageBus,
    MbContextMessageHandler,
)
from msgbus import MBEasyContext
from store_config.message_handler_builder import StoreConfigMessageHandlerBuilder
from store_config.message_handler_builder.config import Config


def default_log_config():
    return {
        "version": 1,
        "formatters": {
            "defaultFormatter": {
                "()": "helper.IsoFormatter"
            }
        },
        "handlers": {
            "stdout": {
                "class": "logging.StreamHandler",
                "formatter": "defaultFormatter",
                "level": "DEBUG",
                "stream": "ext://sys.stdout",
            },
            "stderr": {
                "class": "logging.StreamHandler",
                "formatter": "defaultFormatter",
                "level": "ERROR",
                "stream": "ext://sys.stderr",
            },
        },
        "loggers": {
            "msgbus": {
                "level": "INFO",
                "propagate": True,
            }
        },
        "root": {
            "level": "DEBUG",
            "handlers": [
                "stdout",
                "stderr"
            ]
        },
        "disable_existing_loggers": False
    }


logger = logging.getLogger(__name__)


def replace_env_vars(value: str):
    start, end = (value.find("{"), value.find("}"))
    if start != -1 and end != -1 and end > start + 1:
        var_name = value[start + 1:end]
        var_value = os.environ.get(var_name)
        if var_value is not None:
            return value[:start] + var_value + value[end + 1:]

    return value


def main():

    loader_path = os.environ["LOADERCFG"]
    if os.path.exists(loader_path):
        configuration = cfgtools.read(loader_path)
        import_pydevd(loader_path=loader_path, port=9185)
    else:
        configuration = cfgtools.read_string(loader_path)

    config = Config(store_config=configuration)

    log_path = os.environ["LOG_PATH"]
    try:
        log_dict = json.loads(log_path)
        if len(log_dict) == 0:
            log_dict = default_log_config()
    except ValueError:
        with open(log_path, "rb") as f:
            file_content = f.read().decode()
            log_dict = json.loads(file_content)

    for handler in log_dict.get("handlers", {}).values():
        file_name = handler.get("filename")
        if file_name:
            handler["filename"] = os.path.normpath(replace_env_vars(file_name))

    logging.config.dictConfig(log_dict)

    mb_context = MBEasyContext(name="StoreConfig")
    message_bus = MbContextMessageBus(mb_context=mb_context)

    message_handler_builder = StoreConfigMessageHandlerBuilder(config=config)
    message_handler = MbContextMessageHandler(
        message_bus=message_bus,
        service_name="StoreWideConfig",
        service_type="StoreWideConfig",
        required_services=[],
        message_handler_builder=message_handler_builder,
    )

    logger.info("Starting StoreConfig")
    return message_handler.handle_messages()


if __name__ == "__main__":
    main()
