from social_core.backends.open_id_connect import OpenIdConnectAuth

from ivatar.ivataraccount.models import ConfirmedEmail, Photo
from ivatar.settings import logger, TRUST_EMAIL_FROM_SOCIAL_AUTH_BACKENDS


class FedoraOpenIdConnect(OpenIdConnectAuth):
    name = "fedora"
    USERNAME_KEY = "nickname"
    OIDC_ENDPOINT = "https://id.fedoraproject.org"
    DEFAULT_SCOPE = ["openid", "profile", "email"]
    TOKEN_ENDPOINT_AUTH_METHOD = "client_secret_post"


# Pipeline methods


def add_confirmed_email(backend, user, response, *args, **kwargs):
    """Add a ConfirmedEmail if we trust the auth backend to validate email."""
    if not kwargs.get("is_new", False):
        return None  # Only act on account creation
    if backend.name not in TRUST_EMAIL_FROM_SOCIAL_AUTH_BACKENDS:
        return None
    if ConfirmedEmail.objects.filter(email=user.email).count() > 0:
        # email already exists
        return None
    (confirmed_id, external_photos) = ConfirmedEmail.objects.create_confirmed_email(
        user, user.email, True
    )
    confirmed_email = ConfirmedEmail.objects.get(id=confirmed_id)
    logger.debug(
        "Email %s added upon creation of user %s", confirmed_email.email, user.pk
    )
    photo = Photo.objects.create(user=user, ip_address=confirmed_email.ip_address)
    import_result = photo.import_image("Gravatar", confirmed_email.email)
    if import_result:
        logger.debug("Gravatar image imported for %s", confirmed_email.email)


def associate_by_confirmed_email(backend, details, user=None, *args, **kwargs):
    """
    Associate current auth with a user that has their email address as ConfirmedEmail in the DB.
    """
    if user:
        return None
    email = details.get("email")
    if not email:
        return None
    try:
        confirmed_email = ConfirmedEmail.objects.get(email=email)
    except ConfirmedEmail.DoesNotExist:
        return None
    user = confirmed_email.user
    logger.debug("Found a matching ConfirmedEmail for %s upon login", user.username)
    return {"user": user, "is_new": False}
