"""Model with high-level objects that represents our expectations after migration

It includes objects already existing on target panel, and objects that should
be created on target panel.
"""
from parallels.core.utils.entity import Entity


class TargetModelEntity(Entity):
	"""Base class for all target data model entities"""
	yaml_prefix = 'target'


class Model(TargetModelEntity):
	def __init__(self, plans, resellers, clients):
		self._plans = plans
		self._resellers = resellers
		self._clients = clients

	@property
	def plans(self):
		return self._plans

	@property
	def resellers(self):
		return self._resellers

	@property
	def clients(self):
		return self._clients

	def iter_all_subscriptions(self):
		for client in self.iter_all_clients():
			for subscription in client.subscriptions:
				yield subscription

	def iter_all_clients(self):
		for client in self.clients.itervalues():
			yield client
		for reseller in self.resellers.itervalues():
			for client in reseller.clients:
				yield client


class HostingPlan(TargetModelEntity):
	type = 'hosting'

	def __init__(self, name, is_active, properties, source):
		self._name = name
		self._is_active = is_active
		self._properties = properties
		self._source = source

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

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

	@property
	def properties(self):
		return self._properties

	@property
	def source(self):
		return self._source

	@property
	def is_windows(self):
		return self.properties.get('service-iis', 0) != 0

	@property
	def is_unix(self):
		return self.properties.get('service-hosting', 0) != 0

	@property
	def platforms(self):
		platforms = set()
		if self.is_windows:
			platforms.add('Windows')
		if self.is_unix:
			platforms.add('Unix')
		return platforms


class ResellerPlan(TargetModelEntity):
	type = 'reseller'

	def __init__(self, name, is_active, properties, source):
		self._name = name
		self._is_active = is_active
		self._properties = properties
		self._source = source

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

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

	@property
	def properties(self):
		return self._properties

	@property
	def source(self):
		return self._source

	@property
	def is_windows(self):
		return self.properties.get('service-iis', 0) != 0

	@property
	def is_unix(self):
		return self.properties.get('service-hosting', 0) != 0

	@property
	def platforms(self):
		platforms = set()
		if self.is_windows:
			platforms.add('Windows')
		if self.is_unix:
			platforms.add('Unix')
		return platforms


class AuxiliaryUserRole(TargetModelEntity):
	def __init__(self, name, permissions):
		self._name = name
		self._permissions = permissions

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

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


class Reseller(TargetModelEntity):
	def __init__(
		self, login, password, plan_name, clients, company, personal_info, auxiliary_user_roles, auxiliary_users,
		is_enabled, plans, source, settings, password_type='plain'
	):
		self._login = login
		self._password = password
		self._password_type = password_type
		self._plan_name = plan_name
		self._clients = clients
		self._company = company
		self._personal_info = personal_info
		self._auxiliary_user_roles = auxiliary_user_roles
		self._auxiliary_users = auxiliary_users
		self._is_enabled = is_enabled
		self._plans = plans
		self._source = source
		self._settings = settings

	@property
	def login(self):
		"""Reseller's login

		:rtype: str | unicode
		"""
		return self._login

	@property
	def password(self):
		"""Reseller's password value

		:rtype: str | unicode
		"""
		return self._password

	@property
	def password_type(self):
		"""Type of reseller's password: 'plain' or 'encrypted'

		:rtype: str | unicode
		"""
		return self._password_type

	@property
	def plan_name(self):
		"""Plan to which reseller is assigned to

		:rtype: str | unicode
		"""
		return self._plan_name

	@property
	def clients(self):
		return self._clients

	@property
	def company(self):
		"""
		:rtype: str | unicode
		"""
		return self._company

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

	@property
	def auxiliary_user_roles(self):
		return self._auxiliary_user_roles

	@property
	def auxiliary_users(self):
		return self._auxiliary_users

	@property
	def is_enabled(self):
		return self._is_enabled

	@property
	def plans(self):
		return self._plans

	@property
	def source(self):
		return self._source

	@property
	def settings(self):
		"""Object that can be used by import API to create and configure the reseller, depends on target panel type
		"""
		return self._settings


class AuxiliaryUser(TargetModelEntity):
	def __init__(self, login, password, name, roles, personal_info, is_active, subscription_name, is_domain_admin):
		self._login = login
		self._password = password
		self._name = name
		self._roles = roles
		self._personal_info = personal_info
		self._is_active = is_active
		self._subscription_name = subscription_name
		self._is_domain_admin = is_domain_admin

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

	@login.setter
	def login(self, value):
		self._login = value

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

	@password.setter
	def password(self, value):
		self._password = value

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

	@name.setter
	def name(self, value):
		self._name = value

	@property
	def roles(self):
		return self._roles

	@roles.setter
	def roles(self, value):
		self._roles = value

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

	@personal_info.setter
	def personal_info(self, value):
		self._personal_info = value

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

	@is_active.setter
	def is_active(self, value):
		self._is_active = value

	@property
	def subscription_name(self):
		return self._subscription_name

	@subscription_name.setter
	def subscription_name(self, value):
		self._subscription_name = value

	@property
	def is_domain_admin(self):
		return self._is_domain_admin

	@is_domain_admin.setter
	def is_domain_admin(self, value):
		self._is_domain_admin = value


class Subscription(TargetModelEntity):
	def __init__(
		self, name, plan_name, plan_id, addon_plan_ids, web_ip, web_ip_type, web_ipv6, web_ipv6_type,
		is_enabled, source, is_windows, mail_is_windows, sub_id, group_name, group_id,
		required_resources, additional_resources, sysuser_login
	):
		self._name = name
		self._plan_name = plan_name
		self._plan_id = plan_id
		self._addon_plan_ids = addon_plan_ids
		self._web_ip = web_ip
		self._web_ip_type = web_ip_type
		self._web_ipv6 = web_ipv6
		self._web_ipv6_type = web_ipv6_type
		self._is_enabled = is_enabled
		self._source = source
		self._is_windows = is_windows
		self._mail_is_windows = mail_is_windows
		self._sub_id = sub_id
		self._group_name = group_name
		self._group_id = group_id
		self._required_resources = required_resources
		self._additional_resources = additional_resources
		self._sysuser_login = sysuser_login

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

	@name.setter
	def name(self, value):
		self._name = value

	@property
	def plan_name(self):
		return self._plan_name

	@plan_name.setter
	def plan_name(self, value):
		self._plan_name = value

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

	@plan_id.setter
	def plan_id(self, value):
		self._plan_id = value

	@property
	def addon_plan_ids(self):
		return self._addon_plan_ids

	@addon_plan_ids.setter
	def addon_plan_ids(self, value):
		self._addon_plan_ids = value

	@property
	def web_ip(self):
		return self._web_ip

	@web_ip.setter
	def web_ip(self, value):
		self._web_ip = value

	@property
	def web_ip_type(self):
		return self._web_ip_type

	@web_ip_type.setter
	def web_ip_type(self, value):
		self._web_ip_type = value

	@property
	def web_ipv6(self):
		return self._web_ipv6

	@web_ipv6.setter
	def web_ipv6(self, value):
		self._web_ipv6 = value

	@property
	def web_ipv6_type(self):
		return self._web_ipv6_type

	@web_ipv6_type.setter
	def web_ipv6_type(self, value):
		self._web_ipv6_type = value

	@property
	def is_enabled(self):
		return self._is_enabled

	@is_enabled.setter
	def is_enabled(self, value):
		self._is_enabled = value

	@property
	def source(self):
		return self._source

	@source.setter
	def source(self, value):
		self._source = value

	@property
	def is_windows(self):
		return self._is_windows

	@is_windows.setter
	def is_windows(self, value):
		self._is_windows = value

	@property
	def mail_is_windows(self):
		return self._mail_is_windows

	@mail_is_windows.setter
	def mail_is_windows(self, value):
		self._mail_is_windows = value

	@property
	def sub_id(self):
		return self._sub_id

	@sub_id.setter
	def sub_id(self, value):
		self._sub_id = value

	@property
	def group_name(self):
		return self._group_name

	@group_name.setter
	def group_name(self, value):
		self._group_name = value

	@property
	def group_id(self):
		return self._group_id

	@group_id.setter
	def group_id(self, value):
		self._group_id = value

	@property
	def required_resources(self):
		return self._required_resources

	@required_resources.setter
	def required_resources(self, value):
		self._required_resources = value

	@property
	def additional_resources(self):
		return self._additional_resources

	@additional_resources.setter
	def additional_resources(self, value):
		self._additional_resources = value

	@property
	def sysuser_login(self):
		return self._sysuser_login

	@sysuser_login.setter
	def sysuser_login(self, value):
		self._sysuser_login = value


class Client(TargetModelEntity):
	def __init__(
		self, login, password, subscriptions, company, personal_info, auxiliary_user_roles, auxiliary_users,
		is_enabled, source, target_client, password_type='plain'
	):
		self._login = login
		self._password = password
		self._password_type = password_type
		self._subscriptions = subscriptions
		self._company = company
		self._personal_info = personal_info
		self._auxiliary_user_roles = auxiliary_user_roles
		self._auxiliary_users = auxiliary_users
		self._is_enabled = is_enabled
		self._source = source
		self._target_client = target_client

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

	@login.setter
	def login(self, value):
		self._login = value

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

	@password.setter
	def password(self, value):
		self._password = value

	@property
	def password_type(self):
		return self._password_type

	@property
	def subscriptions(self):
		return self._subscriptions

	@subscriptions.setter
	def subscriptions(self, value):
		self._subscriptions = value

	@property
	def company(self):
		return self._company

	@company.setter
	def company(self, value):
		self._company = value

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

	@personal_info.setter
	def personal_info(self, value):
		self._personal_info = value

	@property
	def auxiliary_user_roles(self):
		return self._auxiliary_user_roles

	@auxiliary_user_roles.setter
	def auxiliary_user_roles(self, value):
		self._auxiliary_user_roles = value

	@property
	def auxiliary_users(self):
		return self._auxiliary_users

	@auxiliary_users.setter
	def auxiliary_users(self, value):
		self._auxiliary_users = value

	@property
	def is_enabled(self):
		return self._is_enabled

	@is_enabled.setter
	def is_enabled(self, value):
		self._is_enabled = value

	@property
	def source(self):
		return self._source

	@source.setter
	def source(self, value):
		self._source = value

	@property
	def target_client(self):
		return self._target_client

	@target_client.setter
	def target_client(self, value):
		self._target_client = value

	def is_admin(self):
		return self.login is None


class PersonalInfo(TargetModelEntity):
	def __init__(
		self, first_name, last_name, email, preferred_email_format, address_line_1, address_line_2,
		city, county, state, postal_code, language_code, locale, country_code,
		primary_phone, additional_phone, fax, mobile_phone
	):
		self._first_name = first_name
		self._last_name = last_name
		self._email = email
		self._preferred_email_format = preferred_email_format
		self._address_line_1 = address_line_1
		self._address_line_2 = address_line_2
		self._city = city
		self._county = county
		self._state = state
		self._postal_code = postal_code
		self._language_code = language_code
		self._locale = locale
		self._country_code = country_code
		self._primary_phone = primary_phone
		self._additional_phone = additional_phone
		self._fax = fax
		self._mobile_phone = mobile_phone

	@property
	def first_name(self):
		return self._first_name

	@property
	def last_name(self):
		return self._last_name

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

	@property
	def preferred_email_format(self):
		return self._preferred_email_format

	@property
	def address_line_1(self):
		return self._address_line_1

	@property
	def address_line_2(self):
		return self._address_line_2

	@property
	def city(self):
		return self._city

	@property
	def county(self):
		return self._county

	@property
	def state(self):
		return self._state

	@property
	def postal_code(self):
		return self._postal_code

	@property
	def language_code(self):
		return self._language_code

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

	@property
	def country_code(self):
		return self._country_code

	@property
	def primary_phone(self):
		return self._primary_phone

	@property
	def additional_phone(self):
		return self._additional_phone

	@property
	def fax(self):
		return self._fax

	@property
	def mobile_phone(self):
		return self._mobile_phone


class Plan(TargetModelEntity):
	def __init__(self, name, is_addon, source, settings):
		self._name = name
		self._is_addon = is_addon
		self._source = source
		self._settings = settings

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

	@property
	def is_addon(self):
		return self._is_addon

	@property
	def source(self):
		return self._source

	@property
	def settings(self):
		"""Object that can be used by import API to create and configure the service template
		Depends on target panel type.
		:rtype:
		"""
		return self._settings
