package com.airlock.iam.base.infrastructure.mapper.jsonapi;

import ch.ergon.restal.jsonapi.Metadata;
import ch.ergon.restal.jsonapi.document.data.Relationship;
import ch.ergon.restal.jsonapi.document.data.Relationships;
import ch.ergon.restal.jsonapi.document.data.ResourceObject;
import ch.ergon.restal.jsonapi.document.data.ResourceObject.Builder;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.net.URI;
import java.util.Optional;

public final class ResourceObjectMetaData {
   private Optional<URI> selfLink = Optional.empty();
   private Relationships relationships = new Relationships();
   private Optional<Metadata> metaData = Optional.empty();

   public ResourceObjectMetaData withSelfLink(URI link) {
      this.selfLink = Optional.of(link);
      return this;
   }

   public ResourceObjectMetaData withRelationship(String key, Relationship relationship) {
      this.relationships.addRelationship(key, relationship);
      return this;
   }

   public ResourceObjectMetaData applyTo(Builder<?> resourceObjectBuilder) {
      this.selfLink.ifPresent(link -> resourceObjectBuilder.linkSelf(link));
      if (this.relationships.getRelationships() != null) {
         this.relationships
            .getRelationships()
            .entrySet()
            .forEach(entry -> resourceObjectBuilder.withRelationship((String)entry.getKey(), (Relationship)entry.getValue()));
      }

      return this;
   }

   public ResourceObjectMetaData applyTo(ResourceObject<?> resourceObject) {
      this.metaData.ifPresent(meta -> resourceObject.setMeta(meta));
      return this;
   }

   public ResourceObjectMetaData withMetaData(Metadata meta) {
      this.metaData = Optional.of(meta);
      return this;
   }

   @SuppressFBWarnings(justification = "generated code")
   public Optional<URI> getSelfLink() {
      return this.selfLink;
   }

   @SuppressFBWarnings(justification = "generated code")
   public Relationships getRelationships() {
      return this.relationships;
   }

   @SuppressFBWarnings(justification = "generated code")
   public Optional<Metadata> getMetaData() {
      return this.metaData;
   }
}
