package com.airlock.iam.base.domain.model.event;

import com.airlock.iam.base.api.domain.model.event.metadata.EventMetadata;
import com.airlock.iam.base.api.domain.model.event.metadata.EventMetadataItem;
import com.airlock.iam.base.api.domain.model.event.metadata.EventMetadataItemType;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

public final class EventMetadataImpl implements EventMetadata {
   private final Map<EventMetadataItemType, EventMetadataItem> items = new HashMap<>();

   public static EventMetadataImpl eventMetadata() {
      return new EventMetadataImpl();
   }

   @Override
   public Collection<EventMetadataItem> items() {
      return List.copyOf(this.items.values());
   }

   @Override
   public Optional<EventMetadataItem> item(EventMetadataItemType type) {
      return Optional.ofNullable(this.items.get(type));
   }

   public EventMetadataImpl put(EventMetadataItem item) {
      this.items.put(item.type(), item);
      return this;
   }

   public EventMetadataImpl maybePut(Optional<? extends EventMetadataItem> item) {
      item.ifPresent(this::put);
      return this;
   }

   public EventMetadataImpl putAll(EventMetadata metadata) {
      metadata.items().forEach(this::put);
      return this;
   }

   @Override
   public String toString() {
      return this.items.values().stream().<CharSequence>map(EventMetadataItem::toString).collect(Collectors.joining(", ", "[", "]"));
   }

   @SuppressFBWarnings(justification = "generated code")
   private EventMetadataImpl() {
   }

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

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