# authentic2 - versatile identity manager
# Copyright (C) 2010-2020 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from collections import OrderedDict

from django import forms
from django.contrib import admin
from django.utils.translation import ugettext as _

from authentic2.custom_user.models import User
from authentic2.forms.widgets import DatalistTextInput
from authentic2.models import Attribute

from . import models


class OIDCClaimMappingForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        claim_widget = self.fields['claim'].widget
        # fill datalist with standard claims from
        # https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
        claim_widget.data = (
            'sub',
            'name',
            'given_name',
            'family_name',
            'nickname' 'preferred_username',
            'profile',
            'picture',
            'website',
            'email',
            'email_verified',
            'gender',
            'birthdate',
            'zoneinfo',
            'locale',
            'phone_number',
            'phone_number_verified',
            'address',
            'updated_at',
        )
        claim_widget.name = 'list__oidcclaim-mapping-inline'
        claim_widget.attrs.update({'list': 'list__oidcclaim-mapping-inline'})

        # Setup the attribute field
        choices = OrderedDict([('', '---------')])
        for name in ('email', 'username', 'first_name', 'last_name'):
            field = User._meta.get_field(name)
            choices[name] = '%s (%s)' % (field.verbose_name.title(), name)
        for attribute in Attribute.objects.all():
            if attribute.name in choices:
                continue
            choices[attribute.name] = '%s (%s)' % (attribute.label, attribute.name)
        choices['ou__slug'] = _('Organizational unit slug (ou__slug)')
        self.fields['attribute'] = forms.ChoiceField(choices=choices.items())

    class Meta:
        model = models.OIDCClaimMapping
        fields = [
            'claim',
            'attribute',
            'verified',
            'required',
            'idtoken_claim',
        ]
        readonly_fields = ['created', 'modified']
        widgets = {
            'claim': DatalistTextInput,
        }


class OIDCClaimMappingInline(admin.TabularInline):
    model = models.OIDCClaimMapping
    form = OIDCClaimMappingForm
    extra = 0


class OIDCProviderAdmin(admin.ModelAdmin):
    list_display = ['name', 'slug', 'client_id', 'ou', 'created', 'modified']
    inlines = [OIDCClaimMappingInline]
    list_filter = ['ou']
    date_hierarchy = 'modified'
    readonly_fields = ['created', 'modified']
    prepopulated_fields = {'slug': ('name',)}


class OIDCAccountAdmin(admin.ModelAdmin):
    list_display = ['provider', 'user', 'sub', 'created', 'modified']
    search_fields = ['user__first_name', 'user__last_name', 'user__email', 'user__username']
    date_hierarchy = 'modified'
    list_filter = ['provider']
    readonly_fields = ['provider', 'user', 'sub', 'created', 'modified']


admin.site.register(models.OIDCProvider, OIDCProviderAdmin)
admin.site.register(models.OIDCAccount, OIDCAccountAdmin)
