# -*- coding: utf-8  -*-
"""
Exception and warning classes used throughout the framework.

Error: Base class, all exceptions should the subclass of this class.

  - NoUsername: Username is not in user-config.py, or it is invalid.
  - UserBlocked: Username or IP has been blocked
  - AutoblockUser: requested action on a virtual autoblock user not valid
  - UserRightsError: insufficient rights for requested action
  - BadTitle: Server responded with BadTitle
  - InvalidTitle: Invalid page title
  - CaptchaError: Captcha is asked and config.solve_captcha == False
  - Server504Error: Server timed out with HTTP 504 code
  - PageNotFound: Page not found (deprecated)
  - i18n.TranslationError: i18n/l10n message not available
  - UnknownExtension: Extension is not defined for this site

SiteDefinitionError: Site loading problem

  - UnknownSite: Site does not exist in Family
  - UnknownFamily: Family is not registered

PageRelatedError: any exception which is caused by an operation on a Page.

  - NoPage: Page does not exist
  - IsRedirectPage: Page is a redirect page
  - IsNotRedirectPage: Page is not a redirect page
  - CircularRedirect: Page is a circular redirect
  - InterwikiRedirectPage: Page is a redirect to another site
  - SectionError: The section specified by # does not exist
  - NotEmailableError: The target user has disabled email
  - NoMoveTarget: An expected move target page does not exist

PageSaveRelatedError: page exceptions within the save operation on a Page
(alias: PageNotSaved).

  - SpamfilterError: MediaWiki spam filter detected a blacklisted URL
  - OtherPageSaveError: misc. other save related exception.
  - LockedPage: Page is locked
      - LockedNoPage: Title is locked against creation
      - CascadeLockedPage: Page is locked due to cascading protection
  - EditConflict: Edit conflict while uploading the page
      - PageDeletedConflict: Page was deleted since being retrieved
      - PageCreatedConflict: Page was created by another user
      - ArticleExistsConflict: Page article already exists
  - NoCreateError: parameter nocreate not allow page creation

ServerError: a problem with the server.

  - FatalServerError: A fatal/non-recoverable server error

WikiBaseError: any issue specific to Wikibase.

  - CoordinateGlobeUnknownException: globe is not implemented yet.
  - EntityTypeUnknownException: entity type is not available on the site.

DeprecationWarning: old functionality replaced by new functionality

PendingDeprecationWarning: problematic code which has not yet been
fully deprecated, possibly because a replacement is not available

RuntimeWarning: problems developers should have fixed, and users need to
be aware of its status.

  - tools._NotImplementedWarning: do not use
  - NotImplementedWarning: functionality not implemented

UserWarning: warnings targetted at users

  - config2._ConfigurationDeprecationWarning: user configuration file problems
  - login._PasswordFileWarning: password file problems
  - ArgumentDeprecationWarning: command line argument problems
  - FamilyMaintenanceWarning: missing information in family definition
"""
#
# (C) Pywikibot team, 2008
#
# Distributed under the terms of the MIT license.
#
from __future__ import absolute_import, unicode_literals

__version__ = '$Id$'

import sys

from pywikibot.tools import UnicodeMixin, _NotImplementedWarning

if sys.version_info[0] > 2:
    unicode = str


class NotImplementedWarning(_NotImplementedWarning):

    """Feature that is no longer implemented."""

    pass


class ArgumentDeprecationWarning(UserWarning):

    """Command line argument that is no longer supported."""

    pass


class FamilyMaintenanceWarning(UserWarning):

    """Family class is missing definitions."""

    pass


class Error(UnicodeMixin, Exception):  # noqa

    """Pywikibot error"""

    # NOTE: UnicodeMixin must be the first object Error class is derived from.
    def __init__(self, arg):
        """Constructor."""
        self.unicode = arg

    def __unicode__(self):
        """Return a unicode string representation."""
        return self.unicode


class PageRelatedError(Error):

    """
    Abstract Exception, used when the exception concerns a particular Page.

    This class should be used when the Exception concerns a particular
    Page, and when a generic message can be written once for all.
    """

    # Preformatted UNICODE message where the page title will be inserted
    # Override this in subclasses.
    # u"Oh noes! Page %s is too funky, we should not delete it ;("
    message = None

    def __init__(self, page, message=None):
        """
        Constructor.

        @param page: Page that caused the exception
        @type page: Page object
        """
        if message:
            self.message = message

        if self.message is None:
            raise Error("PageRelatedError is abstract. Can't instantiate it!")

        self.page = page
        self.title = page.title(asLink=True)
        self.site = page.site

        if '%(' in self.message and ')s' in self.message:
            super(PageRelatedError, self).__init__(self.message % self.__dict__)
        else:
            super(PageRelatedError, self).__init__(self.message % page)

    def getPage(self):
        """Return the page related to the exception."""
        return self.page


class PageSaveRelatedError(PageRelatedError):  # noqa

    """Saving the page has failed"""

    message = u"Page %s was not saved."

    # This property maintains backwards compatibility with
    # the old PageNotSaved which inherited from Error
    # (not PageRelatedError) and exposed the normal 'args'
    # which could be printed
    @property
    def args(self):
        """Expose args."""