from parallels.core.logging import get_logger
from parallels.core.utils.common import cached
from parallels.plesk.source.plesk import messages
from parallels.plesk.source.plesk.hosting_description.plesk_entity.database_user import DatabaseUser
from parallels.plesk.source.plesk.hosting_description.plesk_entity.iis_app_pool import IisAppPool
from parallels.plesk.source.plesk.hosting_description.plesk_entity.mail_responder import MailResponder
from parallels.plesk.source.plesk.hosting_description.plesk_entity.scheduled_task import ScheduledTask
from parallels.plesk.source.plesk.hosting_description.plesk_entity_factory import (
    PleskEntityFactory, format_ids_list
)
from parallels.plesk.source.plesk.hosting_description.utils import data_dump

logger = get_logger(__name__)


class PleskEntityFactory125(PleskEntityFactory):
    """
    Use the decorator data_dump() to catch unhandled exceptions
    """

    @cached
    @data_dump(messages.DATA_DUMP_IIS_APPLICATIONS_POOLS_SETTINGS, {})
    def get_selected_iis_app_pools(self):
        """
        :rtype: dict[str|unicode, parallels.plesk.source.plesk.hosting_description.plesk_entity.iis_app_pool.IisAppPool]
        """
        iis_app_pools = {}

        def get_objects_iis_app_pools(object_type, object_ids):
            rows = self._dump_agent.execute_sql("""
            SELECT `id`, `ownerId`, `ownerType`, `isStarted`, `identity`, `maxProcesses`, `cpuLimit`,
                `cpuLimitAction`, `cpuLimitInterval`, `idleTimeout`, `idleTimeoutAction`, `recyclingByTime`,
                `recyclingByRequests`, `recyclingByVirtualMemory`, `recyclingByPrivateMemory`,
                `managedPipelineMode`
            FROM `IisAppPools`
            WHERE `ownerType` = '{object_type}' AND `ownerId` IN ({object_ids})
        """.format(object_type=object_type, object_ids=format_ids_list(object_ids)))
            return {
                row['id']: IisAppPool(
                    iis_app_pool_id=row['id'], owner_id=row['ownerId'], owner_type=row['ownerType'],
                    is_started=row['isStarted'], identity=row['identity'], max_processes=row['maxProcesses'],
                    cpu_limit=row['cpuLimit'], cpu_limit_action=row['cpuLimitAction'],
                    cpu_limit_interval=row['cpuLimitInterval'], idle_timeout=row['idleTimeout'],
                    idle_timeout_action=row['idleTimeoutAction'], recycling_by_time=row['recyclingByTime'],
                    recycling_by_requests=row['recyclingByRequests'],
                    recycling_by_virtual_memory=row['recyclingByVirtualMemory'],
                    recycling_by_private_memory=row['recyclingByPrivateMemory'],
                    managed_pipeline_mode=row['managedPipelineMode'],
                )
                for row in rows
            }

        for clients_ids in self._iter_ranges(self._get_selected_clients_ids()):
            iis_app_pools.update(get_objects_iis_app_pools('client', clients_ids))
        for domain_ids in self._iter_ranges(self._get_selected_domain_ids()):
            iis_app_pools.update(get_objects_iis_app_pools('domain', domain_ids))

        return iis_app_pools

    @cached
    @data_dump(messages.DATA_DUMP_DATABASES_USERS, {})
    def get_selected_database_users(self):
        """
        :rtype: dict[str|unicode, parallels.plesk.source.plesk.hosting_description.plesk_entity.database_user.DatabaseUser]
        """
        database_users = {}
        for domain_ids in self._iter_ranges(self._get_selected_domain_ids()):
            rows = self._dump_agent.execute_sql("""
                SELECT `id`, `account_id`, `db_id`, `dom_id`, `db_server_id`, `login`, `role`
                FROM `db_users`
                WHERE `dom_id` IN ({domain_ids})
            """.format(domain_ids=format_ids_list(domain_ids)))
            for row in rows:
                database_users[row['id']] = DatabaseUser(
                    database_user_id=row['id'], account_id=row['account_id'], database_id=row['db_id'],
                    domain_id=row['dom_id'], database_server_id=row['db_server_id'], login=row['login'],
                    role=row['role'],
                )
        return database_users

    @cached
    @data_dump(messages.DATA_DUMP_SCHEDULED_TASKS, {})
    def get_selected_scheduled_tasks(self):
        """
        :rtype: dict[str|unicode, parallels.plesk.source.plesk.hosting_description.plesk_entity.scheduled_task.ScheduledTask]
        """
        scheduled_tasks = {}
        for sys_users_ids in self._iter_ranges(self.get_selected_sys_users().keys()):
            rows = self._dump_agent.execute_sql("""
                SELECT `id`, `serviceNodeId`, `sysUserId`, `isActive`, `type`, `phpHandlerId`, `command`, `arguments`,
                `description`, `notify`, `emailType`, `email`, `minute`, `hour`, `dayOfMonth`, `month`, `dayOfWeek`,
                `period`
                FROM `ScheduledTasks`
                WHERE `sysUserId` IN ({sys_users_ids})
            """.format(sys_users_ids=format_ids_list(sys_users_ids)))
            for row in rows:
                scheduled_tasks[row['id']] = ScheduledTask(
                    scheduled_task_id=row['id'], service_node_id=row['serviceNodeId'], sys_user_id=row['sysUserId'],
                    is_active=row['isActive'], scheduled_task_type=row['type'], php_handler_id=row['phpHandlerId'],
                    command=row['command'], arguments=row['arguments'], description=row['description'],
                    notify=row['notify'], email_type=row['emailType'], email=row['email'], minute=row['minute'],
                    hour=row['hour'], day_of_month=row['dayOfMonth'], month=row['month'], day_of_week=row['dayOfWeek'],
                    period=row['period'],
                )
        return scheduled_tasks

    @cached
    @data_dump(messages.DATA_DUMP_MAIL_AUTO_REPLY_SETTINGS, {})
    def get_selected_mail_responders(self):
        """
        :rtype: dict[str|unicode, parallels.plesk.source.plesk.hosting_description.plesk_entity.mail_responder.MailResponder]
        """
        mail_responders = {}
        if self._dump_agent.source_server().is_windows():
            for mail_names_ids in self._iter_ranges(self.get_selected_mail_names().keys()):
                rows = self._dump_agent.execute_sql("""
                    SELECT `id`, `mn_id`, `subject`, `text`, `ans_freq`, `ishtml`, `endDate`
                    FROM `mail_resp`
                    WHERE `mn_id` IN ({mail_names_ids})
                """.format(mail_names_ids=format_ids_list(mail_names_ids)))
                for row in rows:
                    mail_responders[row['id']] = MailResponder(
                        mail_responder_id=row['id'], mail_name_id=row['mn_id'], subject=row['subject'],
                        text=row['text'], ans_freq=row['ans_freq'],
                        content_type='text/html' if row['ishtml'] == 'true' else 'text/plain',
                        end_date=row['endDate'],
                    )
        else:
            for mail_names_ids in self._iter_ranges(self.get_selected_mail_names().keys()):
                rows = self._dump_agent.execute_sql("""
                    SELECT `id`, `mn_id`, `subject`, `text`, `ans_freq`, `content_type`, `endDate`
                    FROM `mail_resp`
                    WHERE `mn_id` IN ({mail_names_ids})
                """.format(mail_names_ids=format_ids_list(mail_names_ids)))
                for row in rows:
                    mail_responders[row['id']] = MailResponder(
                        mail_responder_id=row['id'], mail_name_id=row['mn_id'], subject=row['subject'],
                        text=row['text'], ans_freq=row['ans_freq'],
                        content_type=row['content_type'],
                        end_date=row['endDate'],
                    )
        return mail_responders
