import logging
from logging import Logger

from cfgtools import read
from helper import config_logger
from model.config import Config, PosMap
from systools import sys_parsefilepath
from typing import List


class Configurator(object):

    def __init__(self, loader_path):
        # type: (str) -> None

        self.config = Config()
        self.config.loader_path = loader_path
        self.reader = read(loader_path)

    def read_loader_configs(self):
        # type: () -> Config

        group = "InternalOrder."
        flask_configs = "FlaskConfiguration."
        totem_configs = "TotemConfigs."

        self.config.component_name = str(self.reader.find_value("Identification.ComponentName"))
        self.config.required_services = "|".join(self.reader.find_values(group + "RequiredServices") or [])
        self.config.host = str(self.reader.find_value(group + flask_configs + "Host"))
        self.config.port = str(self.reader.find_value(group + flask_configs + "Port"))
        self.config.cors_origin_hosts = self.reader.find_values(group + flask_configs + "AllowedOriginHosts")
        self.config.show_coupon_button_on = self.reader.find_values(group + totem_configs + "ShowCouponButtonOn")
        self.config.show_products_scroll = self.reader.find_value(group + totem_configs + "ShowProductsScrollBar")

        if self.config.component_name == "InternalOrderMessageBus":
            return self.config

        self.config.allowed_payment_methods = map(int, self.reader.find_values(group + "AllowedPaymentMethods") or [])
        self.config.available_sale_types = "|".join(self.reader.find_values(group + "AvailableSaleTypes") or [])
        self.config.ruptured_items_cache_time = int(self.reader.find_value(group + "RupturedItemsCacheTime") or 10)
        self.config.api_key_mapping = self.build_pos_map(group)
        self.config.images_path = self._get_file_path(group, "ImagesPath")
        self.config.totem_config_path = self._get_file_path(group, "TotemConfigPath")
        self.config.up_sell_part_codes_path = self._get_file_path(group, "UpSellPartCodes")

        cache_group = "{}RefreshCacheTime.".format(group)
        refresh_cache_time = dict(
            menu=int(self.reader.find_value(cache_group + "Menu") or 5),
            fiscal=int(self.reader.find_value(cache_group + "Fiscal") or 5),
            manager=int(self.reader.find_value(cache_group + "Manager") or 5),
            printer=int(self.reader.find_value(cache_group + "Printer") or 5),
            eft=int(self.reader.find_value(cache_group + "Eft") or 5),
        )

        self.config.refresh_cache_time = refresh_cache_time

        return self.config

    def configure_logger(self):
        # type: () -> Logger

        config_logger(self.config.loader_path, self.config.component_name, root_level=logging.DEBUG)
        return logging.getLogger(self.config.component_name)

    def build_pos_map(self, group):
        # type: (str) -> List[PosMap]

        mapped_pos = []
        to_map_groups = self.reader.find_group(group + "PosMap")

        for group in to_map_groups.groups:
            pos_map = PosMap()
            pos_map.pos_id = int(group.name)
            pos_map.api_key = group.find_value("ApiKey")
            pos_map.abstract_pos_id = int(group.find_value("AbstractPosId"))
            pos_map.user_id = int(group.find_value("UserId"))
            pos_map.user_password = int(group.find_value("UserPassword"))

            mapped_pos.append(pos_map)

        return mapped_pos

    def _get_file_path(self, group, path_key):
        file_path = self.reader.find_value(group + path_key) or ""
        file_path = sys_parsefilepath(file_path) if file_path else file_path

        return file_path
