# authentic2-auth-fc - authentic2 authentication for FranceConnect
# Copyright (C) 2019 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 django.template.loader import render_to_string
from django.template.response import TemplateResponse
from django.utils.translation import gettext_noop

from authentic2 import app_settings as a2_app_settings
from authentic2.authenticators import BaseAuthenticator
from authentic2.utils import misc as utils_misc
from authentic2.utils.misc import redirect_to_login

from . import app_settings


class FcAuthenticator(BaseAuthenticator):
    id = 'fc'
    priority = -1

    def enabled(self):
        return app_settings.enable and app_settings.client_id and app_settings.client_secret

    def name(self):
        return gettext_noop('FranceConnect')

    def id(self):
        return 'fc'

    def autorun(self, request, block_id):
        return redirect_to_login(request, login_url='fc-login-or-link')

    def login(self, request, *args, **kwargs):
        if 'nofc' in request.GET:
            return
        fc_user_info = request.session.get('fc_user_info')
        context = kwargs.pop('context', {}).copy()
        context.update(
            {
                'about_url': app_settings.about_url,
                'fc_user_info': fc_user_info,
            }
        )
        context['login_url'] = utils_misc.make_url('fc-login-or-link', keep_params=True, request=request)
        context['block-extra-css-class'] = 'fc-login'
        template = 'authentic2_auth_fc/login.html'
        return TemplateResponse(request, template, context)

    def profile(self, request, *args, **kwargs):
        # We prevent unlinking if the user has no usable password and can't change it
        # because we assume that the password is the unique other mean of authentication
        # and unlinking would make the account unreachable.
        unlink = request.user.has_usable_password() or a2_app_settings.A2_REGISTRATION_CAN_CHANGE_PASSWORD

        account_path = utils_misc.reverse('account_management')
        params = {
            'next': account_path,
        }
        link_url = utils_misc.make_url('fc-login-or-link', params=params)

        context = kwargs.pop('context', {}).copy()
        context.update(
            {
                'unlink': unlink,
                'about_url': app_settings.about_url,
                'link_url': link_url,
            }
        )
        return render_to_string('authentic2_auth_fc/linking.html', context, request=request)

    def registration(self, request, *args, **kwargs):
        return self.login(request, *args, **kwargs)
