from parallels.core.registry import Registry
from parallels.core.utils.entity import Entity


class ServicePlanModel(object):
    def get_list(self, filter_id=None, filter_owner_id=None, filter_name=None):
        """Retrieve list of service plans from target panel which ID listed in given filter

        :type filter_id: list[int] | None
        :type filter_owner_id: list[int] | None
        :type filter_name: list[str] | None
        :rtype: list[parallels.core.hosting_repository.service_plan.ServicePlanEntity]
        """
        raise NotImplementedError()

    def get_by_name(self, name, owner_username=None):
        """Retrieve service plan with given name and owner from target panel

        :type name: str
        :type owner_username: str | None
        :rtype: parallels.core.hosting_repository.service_plan.ServicePlanEntity
        """
        admin_id = Registry.get_instance().get_context().hosting_repository.panel.get_administrator_id(None)
        owner_id = admin_id
        if owner_username is not None:
            for reseller in Registry.get_instance().get_context().hosting_repository.reseller.get_list(
                filter_username=[owner_username]
            ):
                owner_id = reseller.reseller_id
                break

        service_plans = self.get_list(filter_owner_id=[owner_id], filter_name=[name])
        if len(service_plans) < 1:
            return None
        return service_plans[0]

    def create(self, name, owner_username, settings):
        """Create service plan with given name, owner and settings in target panel

        :type name: str
        :type owner_username: str
        :type settings:
        """
        raise NotImplementedError()


class ServicePlanEntity(Entity):
    def __init__(self, service_plan_id, name, owner_id):
        self._service_plan_id = service_plan_id
        self._name = name
        self._owner_id = owner_id
        self._shell = None
        self._database_servers = {}

    @property
    def service_plan_id(self):
        return self._service_plan_id

    @property
    def name(self):
        return self._name

    @property
    def owner_id(self):
        return self._owner_id

    @property
    def shell(self):
        return self._shell

    @shell.setter
    def shell(self, shell):
        self._shell = shell

    @property
    def mysql_database_server(self):
        """MySql database server associated with service plan

        :rtype: parallels.core.hosting_repository.database_server.DatabaseServerEntity
        """
        return self._database_servers.get('mysql')

    @property
    def postgresql_database_server(self):
        """PostgreSql database server associated with service plan

        :rtype: parallels.core.hosting_repository.database_server.DatabaseServerEntity
        """
        return self._database_servers.get('postgresql')

    @property
    def mssql_database_server(self):
        """MSSQL database server associated with service plan

        :rtype: parallels.core.hosting_repository.database_server.DatabaseServerEntity
        """
        return self._database_servers.get('mssql')

    def set_database_server(self, database_server):
        """Set database server associated with service plan

        :type database_server: parallels.core.hosting_repository.database_server.DatabaseServerEntity
        """
        self._database_servers[database_server.type] = database_server

    def get_database_server(self, database_server_type):
        """Retrieve database server of given type, associated with service plan

        :type database_server_type: str
        :rtype: parallels.core.hosting_repository.database_server.DatabaseServerEntity
        """
        return self._database_servers.get(database_server_type)
