"""Entities received from Expand"""

from parallels.core.utils.entity import Entity
from parallels.core.utils.common import default


class ExpandModelEntity(Entity):
    yaml_prefix = 'expand'


class Model(ExpandModelEntity):
    def __init__(
        self, servers=None, centralized_mail_servers=None, expand_clients=None,
        plesk_clients=None, expand_resellers=None,
        assigned_plesk_clients=None, assigned_plesk_domains=None,
        plesk_domains=None, plesk_domain_aliases=None,
        expand_plans=None, dns_server_mapping=None,
        dns_server_ips=None, plesk_server_ips=None,
        mail_server_ips=None, db_server_ips=None
    ):
        self._servers = default(servers, [])
        self._centralized_mail_servers = default(centralized_mail_servers, [])
        self._expand_clients = default(expand_clients, [])
        self._plesk_clients = default(plesk_clients, [])
        self._expand_resellers = default(expand_resellers, [])
        self._assigned_plesk_clients = default(assigned_plesk_clients, [])
        self._assigned_plesk_domains = default(assigned_plesk_domains, [])
        self._plesk_domains = default(plesk_domains, [])
        self._plesk_domain_aliases = default(plesk_domain_aliases, [])
        self._expand_plans = default(expand_plans, [])
        self._dns_server_mapping = default(dns_server_mapping, [])
        self._dns_server_ips = default(dns_server_ips, set())
        self._plesk_server_ips = default(plesk_server_ips, set())
        self._mail_server_ips = default(mail_server_ips, set())
        self._db_server_ips = default(db_server_ips, set())

    @property
    def servers(self):
        """
        :rtype: list[parallels.plesk.source.expand.expand_data.model.Server]
        """
        return self._servers

    @property
    def centralized_mail_servers(self):
        """
        :rtype: list[parallels.plesk.source.expand.expand_data.model.CentralizedMailServer]
        """
        return self._centralized_mail_servers

    @property
    def expand_clients(self):
        """
        :rtype: list[parallels.plesk.source.expand.expand_data.model.ExpandClient]
        """
        return self._expand_clients

    @property
    def plesk_clients(self):
        """
        :rtype: list[parallels.plesk.source.expand.expand_data.model.PleskClient]
        """
        return self._plesk_clients

    @property
    def expand_resellers(self):
        """
        :rtype: list[parallels.plesk.source.expand.expand_data.model.ExpandReseller]
        """
        return self._expand_resellers

    @property
    def assigned_plesk_clients(self):
        """
        :rtype: list[parallels.plesk.source.expand.expand_data.model.AssignedPleskClient]
        """
        return self._assigned_plesk_clients

    @property
    def assigned_plesk_domains(self):
        """
        :rtype: list[parallels.plesk.source.expand.expand_data.model.AssignedPleskDomain]
        """
        return self._assigned_plesk_domains

    @property
    def plesk_domains(self):
        """
        :rtype: list[parallels.plesk.source.expand.expand_data.model.PleskDomain]
        """
        return self._plesk_domains

    @property
    def plesk_domain_aliases(self):
        """
        :rtype: list[parallels.plesk.source.expand.expand_data.model.PleskDomainAlias]
        """
        return self._plesk_domain_aliases

    @property
    def expand_plans(self):
        """
        :rtype: list[parallels.plesk.source.expand.expand_data.model.ExpandPlan]
        """
        return self._expand_plans

    @property
    def dns_server_ips(self):
        """
        :rtype:
        """
        return self._dns_server_ips

    @property
    def plesk_server_ips(self):
        """
        :rtype:
        """
        return self._plesk_server_ips

    @property
    def mail_server_ips(self):
        """
        :rtype:
        """
        return self._mail_server_ips

    @property
    def db_server_ips(self):
        """
        :rtype:
        """
        return self._db_server_ips

    @property
    def dns_server_mapping(self):
        """
        :rtype: list[parallels.plesk.source.expand.expand_data.model.DNSServerMapping]
        """
        return self._dns_server_mapping


class ExpandClient(ExpandModelEntity):
    def __init__(self, id, info, personal_info):
        self._id = id
        self._info = info
        self._personal_info = personal_info

    @property
    def id(self):
        """
        :rtype:
        """
        return self._id

    @property
    def info(self):
        """
        :rtype:
        """
        return self._info

    @property
    def personal_info(self):
        """
        :rtype:
        """
        return self._personal_info


class PleskClient(ExpandModelEntity):
    def __init__(self, id, login, pname, plesk_id, expand_client_id):
        self._id = id
        self._login = login
        self._pname = pname
        self._plesk_id = plesk_id
        self._expand_client_id = expand_client_id

    @property
    def id(self):
        """
        :rtype:
        """
        return self._id

    @property
    def login(self):
        """
        :rtype:
        """
        return self._login

    @property
    def pname(self):
        """
        :rtype:
        """
        return self._pname

    @property
    def plesk_id(self):
        """
        :rtype:
        """
        return self._plesk_id

    @property
    def expand_client_id(self):
        """
        Should be None if Plesk client is not owned by any Expand client

        :rtype:
        """
        return self._expand_client_id


class Server(ExpandModelEntity):
    def __init__(self, id, name, plesk_id):
        self._id = id
        self._name = name
        self._plesk_id = plesk_id

    @property
    def id(self):
        """
        :rtype:
        """
        return self._id

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

    @property
    def plesk_id(self):
        """
        :rtype:
        """
        return self._plesk_id


class CentralizedMailServer(ExpandModelEntity):
    def __init__(self, id, ip, plesk_id, assigned_server_ids):
        self._id = id
        self._ip = ip
        self._plesk_id = plesk_id
        self._assigned_server_ids = assigned_server_ids

    @property
    def id(self):
        """
        :rtype: int
        """
        return self._id

    @property
    def ip(self):
        """
        :rtype: str | unicode
        """
        return self._ip

    @property
    def plesk_id(self):
        """
        :rtype: str | unicode
        """
        return self._plesk_id

    @property
    def assigned_server_ids(self):
        """
        :rtype: list[int]
        """
        return self._assigned_server_ids


class ExpandReseller(ExpandModelEntity):
    def __init__(self, id, login, email, name, password, locale, is_active, limits, permissions, plan_id):
        self._id = id
        self._login = login
        self._email = email
        self._name = name
        self._password = password
        self._locale = locale
        self._is_active = is_active
        self._limits = limits
        self._permissions = permissions
        self._plan_id = plan_id

    @property
    def id(self):
        """
        :rtype:
        """
        return self._id

    @property
    def login(self):
        """
        :rtype:
        """
        return self._login

    @property
    def email(self):
        """
        :rtype:
        """
        return self._email

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

    @property
    def password(self):
        """
        :rtype:
        """
        return self._password

    @property
    def locale(self):
        """
        :rtype:
        """
        return self._locale

    @property
    def is_active(self):
        """
        :rtype:
        """
        return self._is_active

    @property
    def limits(self):
        """
        :rtype:
        """
        return self._limits

    @property
    def permissions(self):
        """
        :rtype:
        """
        return self._permissions

    @property
    def plan_id(self):
        """
        :rtype:
        """
        return self._plan_id


class AssignedPleskClient(ExpandModelEntity):
    """Information about Plesk client to Expand reseller assignment"""

    def __init__(self, client_id, reseller_id, assignee_id, assignee_type):
        self._client_id = client_id
        self._reseller_id = reseller_id
        self._assignee_id = assignee_id
        self._assignee_type = assignee_type

    @property
    def client_id(self):
        """
        :rtype: int
        """
        return self._client_id

    @property
    def reseller_id(self):
        """
        :rtype: int
        """
        return self._reseller_id

    @property
    def assignee_id(self):
        """
        :rtype: int
        """
        return self._assignee_id

    @property
    def assignee_type(self):
        """
        :rtype: str | unicode
        """
        return self._assignee_type


class AssignedPleskDomain(ExpandModelEntity):
    """Information about Plesk domain to Expand reseller assignment"""

    def __init__(self, domain_id, reseller_id):
        self._domain_id = domain_id
        self._reseller_id = reseller_id

    @property
    def domain_id(self):
        """
        :rtype: int
        """
        return self._domain_id

    @property
    def reseller_id(self):
        """
        :rtype: int
        """
        return self._reseller_id


class PleskDomain(ExpandModelEntity):
    def __init__(self, id, name, client_id, plesk_id, tmpl_id, tmpl_name):
        self._id = id
        self._name = name
        self._client_id = client_id
        self._plesk_id = plesk_id
        self._tmpl_id = tmpl_id
        self._tmpl_name = tmpl_name

    @property
    def id(self):
        return self._id

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

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

    @property
    def client_id(self):
        return self._client_id

    @property
    def plesk_id(self):
        return self._plesk_id

    @property
    def tmpl_id(self):
        return self._tmpl_id

    @property
    def tmpl_name(self):
        return self._tmpl_name


class PleskDomainAlias(ExpandModelEntity):
    def __init__(self, id, name):
        self._id = id
        self._name = name

    @property
    def id(self):
        return self._id

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

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


class ExpandPlan(ExpandModelEntity):
    def __init__(self, id, reseller_id, name):
        self._id = id
        self._reseller_id = reseller_id
        self._name = name

    @property
    def id(self):
        """
        :rtype:
        """
        return self._id

    @property
    def reseller_id(self):
        """
        :rtype:
        """
        return self._reseller_id

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


class DNSServerMapping(ExpandModelEntity):
    def __init__(self, plesk_id, dns_server_ip, mode):
        self._plesk_id = plesk_id
        self._dns_server_ip = dns_server_ip
        self._mode = mode

    @property
    def plesk_id(self):
        """
        :rtype: str | unicode
        """
        return self._plesk_id

    @property
    def dns_server_ip(self):
        """
        :rtype: str | unicode
        """
        return self._dns_server_ip

    @property
    def mode(self):
        """
        :rtype: str | unicode
        """
        return self._mode
