from __future__ import absolute_import

from django import forms
from django.db import transaction
from django.http import HttpResponseRedirect, Http404
from django.core.urlresolvers import reverse
from django.views.decorators.csrf import csrf_protect
from django.views.decorators.cache import never_cache
from django.utils.decorators import method_decorator
from django.core.context_processors import csrf
from django.utils.translation import ugettext_lazy as _

import petname
from sudo.decorators import sudo_required

from sentry.models import Authenticator
from sentry.security import capture_security_activity
from sentry.web.frontend.base import BaseView
from sentry.web.decorators import login_required
from sentry.web.helpers import render_to_response
from sentry.web.forms.accounts import TwoFactorForm, ConfirmPasswordForm
from sentry.utils import json


class SmsForm(forms.Form):
    phone_number = forms.CharField(
        label=_('Phone number'), max_length=40
    )


class U2fForm(forms.Form):
    device_name = forms.CharField(
        label=_('Device name'), max_length=60, required=False,
        initial=lambda: petname.Generate(2, ' ').title(),
    )


class TwoFactorSettingsView(BaseView):
    interface_id = None

    @method_decorator(csrf_protect)
    @method_decorator(never_cache)
    @method_decorator(login_required)
    @method_decorator(sudo_required)
    @method_decorator(transaction.atomic)
    def handle(self, request):
        try:
            interface = Authenticator.objects.get_interface(
                request.user, self.interface_id)
        except LookupError:
            raise Http404
        return self.configure(request, interface)

    def make_context(self, request, interface):
        context = csrf(request)
        context['auth'] = interface
        context['page'] = 'security'
        return context

    def delete_authenticator(self, request, interface):
        if interface.authenticator is None:
            return

        with transaction.atomic():
            user = interface.authenticator.user

            capture_security_activity(
                account=request.user,
                type='mfa-removed',
                actor=request.user,
                ip_address=request.META['REMOTE_ADDR'],
                context={
                    'authenticator': interface.authenticator,
                },
                send_email=True,
            )

            interface.authenticator.delete()

            # If this was an authenticator that was a backup interface we just
            # deleted, then nothing happens.
            if interface.is_backup_interface:
                return

            # If however if we delete an actual authenticator and all that
            # remainds are backup interfaces, then we kill them in the
            # process.
            interfaces = Authenticator.objects.all_interfaces_for_user(user)
            backup_interfaces = [x for x in interfaces if x.is_backup_interface]
            if len(backup_interfaces) == len(interfaces):
                for iface in backup_interfaces:
                    iface.authenticator.delete()

                    capture_security_activity(
                        account=request.user,