package com.airlock.iam.admin.application.configuration.generic;

import com.airlock.iam.admin.api.domain.model.token.generic.GenericToken;
import com.airlock.iam.admin.api.domain.model.token.generic.GenericTokenAttributeMapping;
import com.airlock.iam.base.api.domain.model.validation.GenericError;
import com.airlock.iam.base.api.domain.model.validation.ValidationResult;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public final class TokenAttributeMapping implements GenericTokenAttributeMapping {
   private final Map<String, MappingEntry> mappings;

   public TokenAttributeMapping(Map<String, MappingEntry> mappings) {
      this.mappings = mappings;
   }

   @Override
   public boolean isReadOnly(String key, Object object) {
      return this.entry(key).map(MappingEntry::isReadOnly).orElse(false);
   }

   @Override
   public ValidationResult validate(String key, Object object) {
      ValidationResult result = this.isReadOnly(key, object) ? ValidationResult.singleError(key, GenericError.READ_ONLY) : ValidationResult.valid();
      this.entry(key).ifPresent(mapping -> result.mergeWith(mapping.validate(key, object)));
      return result;
   }

   @Override
   public Map<String, Object> getMappedAttributes(GenericToken token) {
      Map<String, Object> map = new HashMap<>();
      this.mappings.forEach((key, value) -> map.put(key, value.getAttributeValueFromToken(token)));
      return map;
   }

   private Optional<MappingEntry> entry(String key) {
      return Optional.ofNullable(this.mappings.get(key));
   }

   @Override
   public void addMappedAttributes(Map<String, Object> attributes, GenericToken token) {
      if (attributes != null) {
         attributes.forEach((key, value) -> {
            MappingEntry entry = this.mappings.get(key);
            if (entry != null) {
               entry.setAttributeValueOnToken(value, token);
            }
         });
      }
   }
}
