from .templates.service_template import ServiceTemplate
from utils.yaml_data_object import YamlDataObject


class Service(YamlDataObject):
    hidden_fields = ['project', 'master']
    yaml_tag = '!Service'
    name: str
    database: str
    version: str or dict
    ports: bool or list
    env_prefix: str
    env_files: bool or list
    env: list
    tech_stack: list
    template: ServiceTemplate

    def __init__(self, name, master, data, project=None):
        super().__init__(data=data)
        self.name = name
        self.master = master
        self.project = project
        self.database = self.try_get('database', None)
        self.version = self.try_get('version', None)
        self.ports = self.try_get('ports', False)
        self.env_prefix = self.try_get('env_prefix', name).upper()
        self.env_files = self.try_get('env_files', False)
        self.env = self.try_get('env', [])
        self.tech_stack = []
        self.template = ServiceTemplate(service=self, name=self.get_required('template'))

    def define_container_names(self):
        self.template.define_container_names()

    def post_load_init(self):
        self.template.post_load_init()

    def generate_compose(self, compose_services, compose_volumes):
        self.template.generate_compose(compose_services, compose_volumes)

    def append_tech_stack(self, tech_stack):
        self.tech_stack += tech_stack
        if self.project:
            self.project.append_tech_stack(tech_stack)

    def get_image_version(self, name):
        if self.version:
            if type(self.version) in [str, int, float]:
                return self.version
            elif type(self.version) == dict:
                return self.version[name]
            else:
                raise Exception("version not found")
        else:
            return 'latest'  # self.master.defaults[name]['version']

    def get_container_by_path(self, container_path):
        if container_path == self.name and self.template.is_single_container:
            return next(iter(self.template.containers.values()))
        else:
            if self.template.entrypoint:
                return self.template.containers[self.template.entrypoint]
            else:
                return self.template.containers[container_path] if container_path in self.template.containers else None

    def get_container_by_tech(self, tech):
        return next(iter(filter(lambda x: tech in x.tech_stack, self.template.containers.values())))

    def get_container_templates(self):
        return self.template.get_container_templates()

from .templates.service_template import ServiceTemplate
from utils.yaml_data_object import YamlDataObject


class Service(YamlDataObject):
    hidden_fields = ['project', 'master']
    yaml_tag = '!Service'
    name: str
    database: str
    version: str or dict
    ports: bool or list
    env_prefix: str
    env_files: bool or list
    env: list
    tech_stack: list
    template: ServiceTemplate

    def __init__(self, name, master, data, project=None):
        super().__init__(data=data)
        self.name = name
        self.master = master
        self.project = project
        self.database = self.try_get('database', None)
        self.version = self.try_get('version', None)
        self.ports = self.try_get('ports', False)
        self.env_prefix = self.try_get('env_prefix', name).upper()
        self.env_files = self.try_get('env_files', False)
        self.env = self.try_get('env', [])
        self.tech_stack = []
        self.template = ServiceTemplate(service=self, name=self.get_required('template'))

    def define_container_names(self):
        self.template.define_container_names()

    def post_load_init(self):
        self.template.post_load_init()

    def generate_compose(self, compose_services, compose_volumes):
        self.template.generate_compose(compose_services, compose_volumes)

    def append_tech_stack(self, tech_stack):
        self.tech_stack += tech_stack
        if self.project:
            self.project.append_tech_stack(tech_stack)

    def get_image_version(self, name):
        if self.version:
            if type(self.version) in [str, int, float]:
                return self.version
            elif type(self.version) == dict:
                return self.version[name]
            else:
                raise Exception("version not found")
        else:
            return 'latest'  # self.master.defaults[name]['version']

    def get_container_by_path(self, container_path):
        if container_path == self.name and self.template.is_single_container:
            return next(iter(self.template.containers.values()))
        else:
            if self.template.entrypoint:
                return self.template.containers[self.template.entrypoint]
            else:
                return self.template.containers[container_path] if container_path in self.template.containers else None

    def get_container_by_tech(self, tech):
        return next(iter(filter(lambda x: tech in x.tech_stack, self.template.containers.values())))

    def get_container_templates(self):
        return self.template.get_container_templates()

# self.master.defaults[name]['version']