from parallels.core.utils.entity import Entity


class SubscriptionModel(object):
    def get_list(self, filter_name=None, filter_owner_id=None):
        """Retrieve list of subscription from target panel by given filter

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

    def get_by_name(self, subscription_name):
        """Retrieve subscription with given name from target panel

        :type subscription_name: str
        :rtype: parallels.core.hosting_repository.subscription.SubscriptionEntity | None
        """
        subscriptions = self.get_list(filter_name=[subscription_name])
        return subscriptions.pop() if len(subscriptions) > 0 else None

    def is_exists(self, subscription_name, guid=None):
        """Check if subscription with given name or guid exists in target panel

        :type subscription_name: str
        :type guid: str | None
        :rtype: bool
        """
        raise NotImplementedError()

    def create(self, subscription, owner, reseller, is_enable_hosting):
        """Create given subscription in target panel
        
        Returns list of non-critical errors (warnings).

        :type subscription: parallels.core.target_data_model.Subscription
        :type owner: parallels.core.target_data_model.Client | parallels.core.target_data_model.Reseller
        :type reseller: parallels.core.target_data_model.Reseller
        :type is_enable_hosting: bool
        :rtype: list[str | unicode]
        """
        raise NotImplementedError()

    def set_username(self, subscription_name, username):
        """Set username of system user associated with given subscription in target panel

        :type subscription_name: str
        :type username: str
        """
        raise NotImplementedError()

    def set_owner(self, subscription_name, owner_username):
        """Set owner of subscription with given name in target panel

        :type subscription_name: str
        :type owner_username: str
        """
        raise NotImplementedError()

    def set_limits(
        self, subscription_name,
        max_domains=None, max_subdomains=None, max_domain_aliases=None, max_databases=None, max_mssql_databases=None,
        max_mail_accounts=None
    ):
        """Set limits for given subscription

        :type subscription_name: str
        :type max_domains: int | None
        :type max_subdomains: int | None
        :type max_domain_aliases: int | None
        :type max_databases: int | None
        :type max_mssql_databases: int | None
        :type max_mail_accounts: int | None
        """
        raise NotImplementedError()

    def set_external_id(self, subscription_name, external_id):
        """Set External ID for given subscription in target panel

        :type subscription_name: str
        :type external_id: str
        """
        raise NotImplementedError()

    def enable_virtual_hosting(self, subscription):
        """Enable virtual hosting for subscription with given name in target panel

        :type subscription: parallels.core.target_data_model.Subscription
        """
        raise NotImplementedError()

    def sync(self, subscription_name):
        """Sync subscription with given name with associated service plan in target panel

        :type subscription_name: str
        """
        raise NotImplementedError()

    def get_dedicated_application_pool_user(self, subscription_name):
        """Retrieve name of dedicated application pool user for given subscription on target panel

        :type subscription_name: str
        """
        raise NotImplementedError()

    def update_security(self, subscription_name):
        """Actualize security metadata for given subscription in target panel

        :type subscription_name: str
        """
        raise NotImplementedError()

    def remove(self, subscription_name):
        """Remove subscription from the server

        :type subscription_name: str | unicode
        """
        raise NotImplementedError()


class SubscriptionEntity(Entity):
    def __init__(self, subscription_id, domain_id, name, status, hosting_type, owner_id):
        self._subscription_id = subscription_id
        self._domain_id = domain_id
        self._name = name
        self._status = status
        self._hosting_type = hosting_type
        self._owner_id = owner_id
        self._service_plan_id = None

    @property
    def subscription_id(self):
        return self._subscription_id

    @property
    def domain_id(self):
        return self._domain_id

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

    @property
    def name_idn(self):
        return self._name.encode('idna')

    @property
    def name_canonical(self):
        return self._name.lower().encode('idna')

    @property
    def status(self):
        return self._status

    @property
    def hosting_type(self):
        return self._hosting_type

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

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

    @service_plan_id.setter
    def service_plan_id(self, service_plan_id):
        self._service_plan_id = service_plan_id

    @property
    def is_active(self):
        return self._status == 0
