package com.airlock.iam.factor.domain.model.fido;

import com.airlock.iam.base.api.domain.model.mapification.MapifiedValues;
import com.airlock.iam.base.domain.model.mapification.MapificationUtils;
import com.airlock.iam.base.domain.model.mapification.MapifiedValuesBuilder;
import com.airlock.iam.factor.domain.model.fido.registration.FidoAttestationType;
import com.airlock.iam.factor.domain.model.fido.registration.FidoAuthenticatorType;
import com.airlock.iam.factor.domain.model.fido.registration.FidoUserVerificationPreference;
import com.airlock.iam.factor.domain.model.fido.registration.ResidentKeyRequirement;

public class FidoCredentialRegistrationSettingsMapifier {
   private static final String PREVENT_DOUBLE_REGISTRATION_KEY = "preventDoubleRegistration";
   private static final String RELYING_PARTY_NAME_KEY = "relyingPartyName";
   private static final String CREDENTIAL_NAME_KEY = "credentialName";
   private static final String PREFERRED_ALGORITHMS_KEY = "preferredAlgorithms";
   private static final String REGISTRATION_TIMEOUT_KEY = "registrationTimeout";
   private static final String AUTHENTICATOR_TYPE_KEY = "authenticatorType";
   private static final String RESIDENT_KEY_KEY = "residentKey";
   private static final String USER_VERIFICATION_KEY = "userVerification";
   private static final String ATTESTATION_TYPE_KEY = "attestationType";
   private static final String AUTO_GENERATE_DISPLAY_NAME_ENABLED = "autoGenerateDisplayNameEnabled";

   public static MapifiedValues mapifyFidoCredentialRegistrationSettings(FidoCredentialRegistrationSettings settings) {
      return MapifiedValuesBuilder.mapifiedValues()
         .put("relyingPartyName", settings.getRelyingPartyName().getName())
         .put("credentialName", settings.getCredentialName().getName())
         .putIfNotEmpty("preferredAlgorithms", MapificationUtils.mapifyCollection(settings.getPreferredAlgorithms(), Enum::name))
         .put("registrationTimeout", MapificationUtils.mapifyDuration(settings.getRegistrationTimeout().getDuration()))
         .put("authenticatorType", settings.getAuthenticatorType().name())
         .put("residentKey", settings.getResidentKey().name())
         .put("userVerification", settings.getUserVerification().name())
         .put("attestationType", settings.getAttestationType().name())
         .put("autoGenerateDisplayNameEnabled", settings.isAutoGenerateDisplayName())
         .put("preventDoubleRegistration", settings.isPreventDoubleRegistration())
         .build();
   }

   public static FidoCredentialRegistrationSettings demapifyFidoCredentialRegistrationSettings(MapifiedValues values) {
      return new FidoCredentialRegistrationSettings(
         FidoRelyingPartyName.relyingPartyName(values.get("relyingPartyName")),
         FidoCredentialName.credentialName(values.get("credentialName")),
         values.<String>getList("preferredAlgorithms")
            .stream()
            .map(v -> MapificationUtils.demapifyEnumOfClass(v, SupportedCoseAlgorithmIdentifier.class))
            .toList(),
         values.demapifyValue("registrationTimeout", v -> FidoTimeout.timeout(MapificationUtils.demapifyDuration(v))),
         MapificationUtils.demapifyEnumOfClass(values.get("authenticatorType"), FidoAuthenticatorType.class),
         MapificationUtils.demapifyEnumOfClass(values.get("residentKey"), ResidentKeyRequirement.class),
         MapificationUtils.demapifyEnumOfClass(values.get("userVerification"), FidoUserVerificationPreference.class),
         MapificationUtils.demapifyEnumOfClass(values.get("attestationType"), FidoAttestationType.class),
         values.<Boolean>get("autoGenerateDisplayNameEnabled"),
         values.<Boolean>get("preventDoubleRegistration")
      );
   }
}
