package com.airlock.iam.flow.shared.domain.model.attributes;

import com.airlock.iam.base.api.domain.model.mapification.MapifiedValues;
import com.airlock.iam.base.domain.model.mapification.MapificationUtils;
import com.airlock.iam.base.misc.collection.IamMaps;
import com.airlock.iam.common.domain.service.mapification.Mapifier;
import com.airlock.iam.elog.api.ELogger;
import com.airlock.iam.elog.api.ELoggerFactory;
import com.airlock.iam.flow.shared.api.domain.model.session.UserSessionScopedFlowAttribute;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Map;

public final class ScriptExecutionResultFlowAttribute implements UserSessionScopedFlowAttribute<ScriptExecutionResultFlowAttribute> {
   private final Map<String, Object> attributes;
   private static final ELogger LOG = ELoggerFactory.getLogger(ScriptExecutionResultFlowAttribute.class);

   public static ScriptExecutionResultFlowAttribute scriptExecutionResultFlowAttribute(Map<String, Object> result) {
      return new ScriptExecutionResultFlowAttribute(result);
   }

   public ScriptExecutionResultFlowAttribute mergeWith(ScriptExecutionResultFlowAttribute newAttribute) {
      Map<String, Object> merged = IamMaps.mergeMaps(this.attributes, newAttribute.attributes, this::logWhenOverriding);
      return scriptExecutionResultFlowAttribute(merged);
   }

   public ScriptExecutionResultFlowAttribute copyAttribute() {
      return scriptExecutionResultFlowAttribute(this.attributes);
   }

   @Override
   public MapifiedValues mapify() {
      return MapificationUtils.mapifyMap(this.attributes, Mapifier.getInstance()::mapify);
   }

   public static ScriptExecutionResultFlowAttribute demapify(MapifiedValues values) {
      return new ScriptExecutionResultFlowAttribute(MapificationUtils.demapifyMap(values.asMap(), Mapifier.getInstance()::demapify));
   }

   private void logWhenOverriding(String key) {
      LOG.debug("Scriptable: replacing attribute for key [" + key + "]");
   }

   @SuppressFBWarnings(justification = "generated code")
   public Map<String, Object> getAttributes() {
      return this.attributes;
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public boolean equals(Object o) {
      if (o == this) {
         return true;
      } else if (!(o instanceof ScriptExecutionResultFlowAttribute other)) {
         return false;
      } else {
         Object this$attributes = this.attributes;
         Object other$attributes = other.attributes;
         return this$attributes == null ? other$attributes == null : this$attributes.equals(other$attributes);
      }
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public int hashCode() {
      int PRIME = 59;
      int result = 1;
      Object $attributes = this.attributes;
      return result * 59 + ($attributes == null ? 43 : $attributes.hashCode());
   }

   @SuppressFBWarnings(justification = "generated code")
   @Override
   public String toString() {
      return "ScriptExecutionResultFlowAttribute(attributes=" + this.getAttributes() + ")";
   }

   @SuppressFBWarnings(justification = "generated code")
   private ScriptExecutionResultFlowAttribute(Map<String, Object> attributes) {
      this.attributes = attributes;
   }
}
