import logging

from parallels.core import messages
from parallels.core import target_data_model as target_model
from parallels.core.converter.business_objects.common import SOURCE_TARGET
from parallels.core.reports.model.issue import Issue
from parallels.core.utils.common import group_by_id


class ClientsConverter(object):
    """Generate list of customers ready to import to target panel.

    Clients converter takes the following information:
    - Plesk backup or other source of information
    about clients on source servers
    - Information about clients that already exist on
    target panel
    - Migration list, which contains list of resellers that
    will be used during migration

    Clients converter:
    - Converts each client we need to migrate to
    format ready to import to target panel.
    - Performs conflict resolution, if client exists on multiple
    source panel, or already exists on target panel.

    Result is a list of clients ready to import to target panel.
    """

    logger = logging.getLogger(u'%s.Converter' % __name__)

    @staticmethod
    def assign_clients_to_resellers(admin_clients, resellers, clients, clients_mapping, report):
        clients_by_logins = group_by_id(clients, lambda c: c.login)
        resellers_by_logins = group_by_id(resellers, lambda r: r.login)
        for client_login, reseller_login in clients_mapping.items():
            if client_login not in clients_by_logins:
                # If customer exists in migration list, but does not exist on source
                # and target panels - simply ignore it here. Issue should be reported by
                # "convert_clients" function
                continue

            client = clients_by_logins[client_login]

            if reseller_login is not None and reseller_login in resellers_by_logins:
                reseller = resellers_by_logins[reseller_login]
                reseller.clients.append(client)
            elif reseller_login is None:
                admin_clients[client.login] = client
            else:
                report.add_issue(
                    'client_does_not_exist', Issue.SEVERITY_ERROR,
                    messages.CLIENT_IS_MAPPED_AN_UNEXISTING_RESELLER % reseller_login,
                    messages.CREATE_RESELLER_IN_DESTINATION_PANEL_MAP)

    @staticmethod
    def create_client_stub_from_existing_client(existing_client):
        return target_model.Client(
            login=existing_client.username,
            source=SOURCE_TARGET,
            personal_info=target_model.PersonalInfo.create_none_filled(
                email=existing_client.email,
                first_name=existing_client.first_name,
                last_name=existing_client.last_name
            ),
            password=None, subscriptions=[], company=None,
            auxiliary_user_roles=[], auxiliary_users=[], is_enabled=None,
            target_client=existing_client
        )

    @staticmethod
    def create_fake_client(login):
        return target_model.Client(
            login=login, password=None, subscriptions=[],
            company=None,
            personal_info=target_model.PersonalInfo(
                first_name=None,
                last_name=None,
                email=None,
                address=None,
                city=None,
                county=None,
                state=None,
                postal_code=None,
                language_code=None,
                locale=None,
                country_code=None,
                primary_phone=None,
                additional_phone=None,
                fax=None,
                mobile_phone=None,
                comment=None,
                im=None,
                im_type=None,
            ),
            auxiliary_user_roles=[],
            auxiliary_users=[],
            is_enabled=True,
            source=SOURCE_TARGET,
            target_client=None
        )
