package com.airlock.iam.common.infrastructure.restclient;

import com.airlock.iam.common.application.configuration.restclient.RestClientConfig;
import com.airlock.iam.common.application.configuration.restclient.StaticRestRequestHeaderConfig;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class StaticRestRequestHeaderService {
   private final RestClientConfig.StaticHeaderStrategy staticHeaderStrategy;
   private final Map<String, List<Object>> headers;

   public StaticRestRequestHeaderService(
      List<StaticRestRequestHeaderConfig> staticRestRequestHeaders, RestClientConfig.StaticHeaderStrategy staticHeaderStrategy
   ) {
      this.headers = staticRestRequestHeaders.stream()
         .collect(Collectors.toMap(StaticRestRequestHeaderConfig::getHeaderName, value -> List.of(value.getHeaderValue())));
      this.staticHeaderStrategy = staticHeaderStrategy;
   }

   public RestRequest addStaticRequestHeaders(RestRequest request) {
      if (this.headers.isEmpty()) {
         return request;
      }

      Map<String, List<Object>> combinedHeaders = new HashMap<>(request.getHeaders());
      if (this.staticHeaderStrategy.equals(RestClientConfig.StaticHeaderStrategy.OVERWRITE_EXISTING)) {
         combinedHeaders.putAll(this.headers);
      } else {
         this.headers.forEach(combinedHeaders::putIfAbsent);
      }

      return RestRequest.builder()
         .path(request.getPath())
         .method(request.getMethod())
         .queryValues(request.getQueryValues())
         .headers(combinedHeaders)
         .cookies(request.getCookies())
         .body(request.getBody())
         .build();
   }

   @SuppressFBWarnings(justification = "generated code")
   public static StaticRestRequestHeaderService.StaticRestRequestHeaderServiceBuilder builder() {
      return new StaticRestRequestHeaderService.StaticRestRequestHeaderServiceBuilder();
   }

   @SuppressFBWarnings(justification = "generated code")
   public StaticRestRequestHeaderService(RestClientConfig.StaticHeaderStrategy staticHeaderStrategy, Map<String, List<Object>> headers) {
      this.staticHeaderStrategy = staticHeaderStrategy;
      this.headers = headers;
   }

   @SuppressFBWarnings(justification = "generated code")
   public static class StaticRestRequestHeaderServiceBuilder {
      @SuppressFBWarnings(justification = "generated code")
      private RestClientConfig.StaticHeaderStrategy staticHeaderStrategy;
      @SuppressFBWarnings(justification = "generated code")
      private Map<String, List<Object>> headers;

      @SuppressFBWarnings(justification = "generated code")
      StaticRestRequestHeaderServiceBuilder() {
      }

      @SuppressFBWarnings(justification = "generated code")
      public StaticRestRequestHeaderService.StaticRestRequestHeaderServiceBuilder staticHeaderStrategy(
         RestClientConfig.StaticHeaderStrategy staticHeaderStrategy
      ) {
         this.staticHeaderStrategy = staticHeaderStrategy;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public StaticRestRequestHeaderService.StaticRestRequestHeaderServiceBuilder headers(Map<String, List<Object>> headers) {
         this.headers = headers;
         return this;
      }

      @SuppressFBWarnings(justification = "generated code")
      public StaticRestRequestHeaderService build() {
         return new StaticRestRequestHeaderService(this.staticHeaderStrategy, this.headers);
      }

      @SuppressFBWarnings(justification = "generated code")
      @Override
      public String toString() {
         return "StaticRestRequestHeaderService.StaticRestRequestHeaderServiceBuilder(staticHeaderStrategy="
            + this.staticHeaderStrategy
            + ", headers="
            + this.headers
            + ")";
      }
   }
}
