from collections import namedtuple
from inspect import isclass

from django.utils.translation import gettext_lazy as _


__all__ = (
    'LOG',
    'LOG_BY_ID',
    'LOG_KEEP',
)


class _LOG:
    action_class = None


class CREATE_ADDON(_LOG):
    id = 1
    action_class = 'add'
    format = _('{addon} was created.')
    keep = True
    show_user_to_developer = True


class EDIT_PROPERTIES(_LOG):
    """Expects: addon"""

    id = 2
    action_class = 'edit'
    format = _('{addon} properties edited.')
    show_user_to_developer = True


class EDIT_DESCRIPTIONS(_LOG):
    id = 3
    action_class = 'edit'
    format = _('{addon} description edited.')
    show_user_to_developer = True


class EDIT_CATEGORIES(_LOG):
    id = 4
    action_class = 'edit'
    format = _('Categories edited for {addon}.')
    show_user_to_developer = True


class ADD_USER_WITH_ROLE(_LOG):
    id = 5
    action_class = 'add'
    format = _('{0.name} ({1}) added to {addon}.')
    keep = True
    show_user_to_developer = True


class REMOVE_USER_WITH_ROLE(_LOG):
    id = 6
    action_class = 'delete'
    # L10n: {0} is the user being removed, {1} is their role.
    format = _('{0.name} ({1}) removed from {addon}.')
    keep = True
    show_user_to_developer = True


class EDIT_CONTRIBUTIONS(_LOG):
    id = 7
    action_class = 'edit'
    format = _('Contributions for {addon}.')


class USER_DISABLE(_LOG):
    id = 8
    format = _('{addon} disabled.')
    keep = True
    show_user_to_developer = True


class USER_ENABLE(_LOG):
    id = 9
    format = _('{addon} enabled.')
    keep = True
    show_user_to_developer = True


class CHANGE_STATUS(_LOG):
    id = 12
    # L10n: {status} is the status
    format = _('{addon} status changed to {status}.')
    keep = True


class ADD_VERSION(_LOG):
    id = 16
    action_class = 'add'
    format = _('{version} added to {addon}.')
    keep = True
    store_ip = True
    show_user_to_developer = True


class EDIT_VERSION(_LOG):
    id = 17
    action_class = 'edit'
    format = _('{version} edited for {addon}.')
    show_user_to_developer = True


class DELETE_VERSION(_LOG):
    id = 18
    action_class = 'delete'
    # Note, {0} is a string not a version since the version is deleted.
    # L10n: {0} is the version number
    format = _('Version {0} deleted from {addon}.')
    keep = True
    show_user_to_developer = True


class ADD_FILE_TO_VERSION(_LOG):
    id = 19
    action_class = 'add'
    format = _('File {0.name} added to {version} of {addon}.')


class DELETE_FILE_FROM_VERSION(_LOG):
    """
    Expecting: addon, filename, version
    Because the file is being deleted, filename and version
    should be strings and not the object.
    """

    id = 20
    action_class = 'delete'
    format = _('File {0} deleted from {version} of {addon}.')


class APPROVE_VERSION(_LOG):
    id = 21
    action_class = 'approve'
    format = _('{addon} {version} approved.')
    short = _('Approved')
    keep = True
    review_email_user = True
    review_queue = True
    reviewer_review_action = True


class PRELIMINARY_VERSION(_LOG):
    id = 42
    action_class = 'approve'
    format = _('{addon} {version} given preliminary review.')
    short = _('Preliminarily approved')
    keep = True
    review_email_user = True
    review_queue = True
    reviewer_review_action = True


class REJECT_VERSION(_LOG):
    # takes add-on, version, reviewtype
    id = 43
    action_class = 'reject'
    format = _('{addon} {version} rejected.')
    short = _('Rejected')
    keep = True
    review_email_user = True
    review_queue = True
    reviewer_review_action = True


class RETAIN_VERSION(_LOG):
    # takes add-on, version, reviewtype
    id = 22
    format = _('{addon} {version} retained.')
    short = _('Retained')
    keep = True
    review_email_user = True
    review_queue = True
    reviewer_review_action = True


class ESCALATE_VERSION(_LOG):
    # takes add-on, version, reviewtype
    id = 23
    format = _('{addon} {version} escalated.')
    short = _('Super review requested')
    keep = True
    review_email_user = True
    review_queue = True
    hide_developer = True


class REQUEST_VERSION(_LOG):
    # takes add-on, version, reviewtype
    id = 24
    format = _('{addon} {version} review requested.')
    short = _('Review requested')
    keep = True
    review_email_user = True
    review_queue = True


# Obsolete now that we have pending rejections, kept for compatibility.
class REQUEST_INFORMATION(_LOG):
    id = 44
    format = _('{addon} {version} more information requested.')
    short = _('More information requested')
    keep = True
    review_email_user = True
    review_queue = True
    reviewer_review_action = True


# Obsolete now that we've split the requests for admin review into separate
# actions for code/theme/content, but kept for compatibility with old history,
# and also to re-use the `sanitize` property.
class REQUEST_SUPER_REVIEW(_LOG):
    id = 45
    format = _('{addon} {version} super review requested.')
    short = _('Super review requested')
    keep = True
    review_queue = True
    sanitize = _(
        "The addon has been flagged for Admin Review.  It's still "
        'in our review queue, but it will need to be checked by one '
        'of our admin reviewers. The review might take longer than '
        'usual.'
    )
    reviewer_review_action = True


class COMMENT_VERSION(_LOG):
    id = 49
    format = _('Comment on {addon} {version}.')
    short = _('Commented')
    keep = True
    review_queue = True
    hide_developer = True
    reviewer_review_action = True


class ADD_TAG(_LOG):
    id = 25
    action_class = 'tag'
    format = _('{tag} added to {addon}.')
    show_user_to_developer = True


class REMOVE_TAG(_LOG):
    id = 26
    action_class = 'tag'
    format = _('{tag} removed from {addon}.')
    show_user_to_developer = True


class ADD_TO_COLLECTION(_LOG):
    id = 27
    action_class = 'collection'
    format = _('{addon} added to {collection}.')
    show_user_to_developer = True


class REMOVE_FROM_COLLECTION(_LOG):
    id = 28
    action_class = 'collection'
    format = _('{addon} removed from {collection}.')
    show_user_to_developer = True


class ADD_RATING(_LOG):
    id = 29
    action_class = 'review'
    format = _('{rating} for {addon} written.')
    show_user_to_developer = True


# TODO(davedash): Add these when we do the admin site
class ADD_RECOMMENDED_CATEGORY(_LOG):
    id = 31
    action_class = 'edit'
    # L10n: {0} is a category name.
    format = _('{addon} featured in {0}.')


class REMOVE_RECOMMENDED_CATEGORY(_LOG):
    id = 32
    action_class = 'edit'
    # L10n: {0} is a category name.
    format = _('{addon} no longer featured in {0}.')


class ADD_RECOMMENDED(_LOG):
    id = 33
    format = _('{addon} is now featured.')
    keep = True


class REMOVE_RECOMMENDED(_LOG):
    id = 34
    format = _('{addon} is no longer featured.')
    keep = True


class ADD_APPVERSION(_LOG):
    id = 35
    action_class = 'add'
    # L10n: {0} is the application, {1} is the version of the app
    format = _('{0} {1} added.')


class CHANGE_USER_WITH_ROLE(_LOG):
    """Expects: author.user, role, addon"""

    id = 36
    # L10n: {0} is a user, {1} is their role
    format = _('{0.name} role changed to {1} for {addon}.')
    keep = True
    show_user_to_developer = True


class CHANGE_LICENSE(_LOG):
    """Expects: license, addon"""

    id = 37
    action_class = 'edit'
    format = _('{addon} is now licensed under {0}.')
    show_user_to_developer = True


class CHANGE_POLICY(_LOG):
    id = 38
    action_class = 'edit'
    format = _('{addon} policy changed.')
    show_user_to_developer = True


class CHANGE_ICON(_LOG):
    id = 39
    action_class = 'edit'
    format = _('{addon} icon changed.')
    show_user_to_developer = True


class APPROVE_RATING(_LOG):
    id = 40
    action_class = 'approve'
    format = _('{rating} for {addon} approved.')
    reviewer_format = _('{user} approved {rating} for {addon}.')
    keep = True
    reviewer_event = True


class DELETE_RATING(_LOG):
    """Requires rating.id and add-on objects."""

    id = 41
    action_class = 'review'
    format = _('Review {rating} for {addon} deleted.')
    reviewer_format = _('{user} deleted {rating} for {addon}.')
    keep = True
    reviewer_event = True


class MAX_APPVERSION_UPDATED(_LOG):
    id = 46
    format = _('Application max version for {version} updated.')
    show_user_to_developer = True


class BULK_VALIDATION_EMAILED(_LOG):
    id = 47
    format = _('Authors emailed about compatibility of {version}.')


class BULK_VALIDATION_USER_EMAILED(_LOG):
    id = 130
    format = _('Email sent to Author about add-on compatibility.')


class CHANGE_PASSWORD(_LOG):
    id = 48
    format = _('Password changed.')


class APPROVE_VERSION_WAITING(_LOG):
    id = 53
    action_class = 'approve'
    format = _('{addon} {version} approved but waiting to be made public.')
    short = _('Approved but waiting')
    keep = True
    review_email_user = True
    review_queue = True


class USER_EDITED(_LOG):
    id = 60
    format = _('Account updated.')


class CUSTOM_TEXT(_LOG):
    id = 98
    format = '{0}'


class CUSTOM_HTML(_LOG):
    id = 99
    format = '{0}'


class OBJECT_ADDED(_LOG):
    id = 100
    format = _('Created: {0}.')
    admin_event = True


class OBJECT_EDITED(_LOG):
    id = 101
    format = _('Edited field: {2} set to: {0}.')
    admin_event = True


class OBJECT_DELETED(_LOG):
    id = 102
    format = _('Deleted: {1}.')
    admin_event = True


class ADMIN_USER_EDITED(_LOG):
    id = 103
    format = _('User {user} edited, reason: {1}')
    admin_event = True


class ADMIN_USER_ANONYMIZED(_LOG):