from typing import List
from .python_util import filter_none


class Validateable:
    def __validate_is_not_empty__(self, field_name: str) -> List[str]:
        value = self.__dict__[field_name]
        if value is None or value == "":
            return [f"Field '{field_name}' may not be empty."]
        else:
            return []

    def validate(self) -> List[str]:
        return []

    def is_valid(self) -> bool:
        return len(self.validate()) < 1


class Build(Validateable):
    def __init__(self, project, config):
        self.stage = config["stage"]
        self.project_root_path = config["project_root_path"]
        self.module = config["module"]
        self.build_dir_name = config["build_dir_name"]
        self.stack = {}
        self.project = project

    def name(self):
        return self.project.name

    def build_path(self):
        path = [self.project_root_path, self.build_dir_name, self.name(), self.module]
        return "/".join(filter_none(path))

    # TODO: these functions should be located at TerraformBuild later on.
    def update_runtime_config(self, fqdn, ipv4, ipv6):
        self.__put__('fqdn', fqdn)
        self.__put__('ipv4', ipv4)
        self.__put__('ipv6', ipv6)

    def __put__(self, key, value):
        self.stack[key] = value

    def __get__(self, key):
        return self.stack[key]

    def __get_keys__(self, keys):
        result = {}
        for key in keys:
            result[key] = self.__get__(key)
        return result


class DockerBuild(Validateable):
    def __init__(self, project, config):
        project.build_depends_on("dda-python-terraform")
        self.build = Build(project, config)
        self.dockerhub_user = config["dockerhub_user"]
        self.dockerhub_password = config["dockerhub_password"]
        self.use_package_common_files = config["use_package_common_files"]
        self.build_commons_path = config["build_commons_path"]
        self.docker_build_commons_dir_name = config["docker_build_commons_dir_name"]
        self.docker_publish_tag = config["docker_publish_tag"]

    def docker_build_commons_path(self):
        list = [self.build_commons_path, self.docker_build_commons_dir_name]
        return "/".join(filter_none(list)) + "/"


class C4kBuild(Validateable):
    def __init__(self, build: Build, project, config):
        self.build = build
        self.c4k_mixin_config = config["C4kMixin"]["Config"]
        self.c4k_mixin_auth = config["C4kMixin"]["Auth"]
        tmp = self.c4k_mixin_config["mon-cfg"]
        tmp.update({"cluster-name": self.build.module, "cluster-stage": self.build.stage})
        self.c4k_mixin_config.update({"mon-cfg": tmp})

    def update_runtime_config(self, fqdn, ipv4, ipv6):
        self.build.update_runtime_config(fqdn, ipv4, ipv6)

    def config(self):
        fqdn = self.build.__get__('fqdn')
        self.c4k_mixin_config.update({'fqdn': fqdn})
        return self.c4k_mixin_config