from parallels.core.logging import get_logger
from parallels.core import messages
from parallels.core import MigrationNoContextError
from parallels.core.registry import Registry
from parallels.core.utils.common import is_run_on_windows
from parallels.core.utils.windows_utils import is_run_by_built_in_administrator, is_built_in_administrator
from parallels.core.utils.json_utils import encode_json
from parallels.core.actions.base.common_action import CommonAction
from parallels.core.actions.utils.logging_properties import LoggingProperties

logger = get_logger(__name__)


class CheckTargetAccountAction(CommonAction):
    def get_description(self):
        """Get short description of action as string

        :rtype: str
        """
        return messages.ACTION_CHECK_TARGET_ACCOUNT

    def get_failure_message(self, global_context):
        """Get message for situation when action failed

        This message should contain impact and ways to resolve or work the
        problem around

        Arguments:
        - global_context - registry with different objects that reused among different actions

        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :rtype: str | unicode
        """
        return messages.ACTION_CHECK_TARGET_ACCOUNT_FAILED

    def filter_action(self, global_context):
        """Check whether we should run this action or not. By default True - action should be executed.

        Arguments:
        - global_context - registry with different objects that reused among different actions

        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :rtype: bool
        """
        return is_run_on_windows()

    def get_logging_properties(self):
        """Get how action should be logged to migration tools end-user

        :rtype: parallels.core.actions.utils.logging_properties.LoggingProperties
        """
        return LoggingProperties(info_log=False)

    def run(self, global_context):
        """Run action

        Arguments:
        - global_context - registry with different objects that reused among different actions

        :type global_context: parallels.core.global_context.GlobalMigrationContext
        :rtype: None
        """
        username = getattr(global_context.options, 'username', None)
        try:
            if username is None:
                result = is_run_by_built_in_administrator()
            else:
                result = is_built_in_administrator(global_context.options.username)
        except Exception as e:
            # do not block migration if unable to check administrator account for some reason,
            # just log error and skip it
            logger.error(
                messages.ACTION_CHECK_TARGET_ACCOUNT_UNABLE_RUN.format(
                    exception=e
                ) if username is None else
                messages.ACTION_CHECK_TARGET_ACCOUNT_UNABLE_SPECIFIED.format(
                    username=username,
                    exception=e
                )
            )
            return

        if Registry.get_instance().get_context().options.quiet:
            print(encode_json(result))
        else:
            if result:
                logger.info(
                    messages.ACTION_CHECK_TARGET_ACCOUNT_BUILT_IN_RUN if username is None else
                    messages.ACTION_CHECK_TARGET_ACCOUNT_BUILT_IN_SPECIFIED.format(
                        username=username
                    )
                )
            else:
                raise MigrationNoContextError(
                    messages.ACTION_CHECK_TARGET_ACCOUNT_NOT_BUILT_IN_RUN if username is None else
                    messages.ACTION_CHECK_TARGET_ACCOUNT_NOT_BUILT_IN_SPECIFIED.format(
                        username=username
                    )
                )
