package com.hubspot.singularity.api;

import java.util.Collections;
import java.util.List;
import java.util.Map;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.Optional;

import io.swagger.v3.oas.annotations.media.Schema;

@Schema(description = "Describes a request to search for task logs in s3")
public class SingularityS3SearchRequest {
  private final Map<String, List<String>> requestsAndDeploys;
  private final List<String> taskIds;
  private final Optional<Long> start;
  private final Optional<Long> end;
  private final boolean excludeMetadata;
  private final boolean listOnly;
  private final Optional<Integer> maxPerPage;
  private final Map<String, ContinuationToken> continuationTokens;

  @JsonCreator

  public SingularityS3SearchRequest(@JsonProperty("requestsAndDeploys") Map<String, List<String>> requestsAndDeploys,
                                    @JsonProperty("taskIds") List<String> taskIds,
                                    @JsonProperty("start") Optional<Long> start,
                                    @JsonProperty("end") Optional<Long> end,
                                    @JsonProperty("excludeMetadata") boolean excludeMetadata,
                                    @JsonProperty("listOnly") boolean listOnly,
                                    @JsonProperty("maxPerPage") Optional<Integer> maxPerPage,
                                    @JsonProperty("continuationTokens") Map<String, ContinuationToken> continuationTokens) {
    this.requestsAndDeploys = requestsAndDeploys != null ? requestsAndDeploys : Collections.<String, List<String>>emptyMap();
    this.taskIds = taskIds != null ? taskIds : Collections.<String>emptyList();
    this.start = start;
    this.end = end;
    this.excludeMetadata = excludeMetadata;
    this.listOnly = listOnly;
    this.maxPerPage = maxPerPage;
    this.continuationTokens = continuationTokens != null ? continuationTokens : Collections.<String, ContinuationToken>emptyMap();
  }

  @Schema(description = "A map of request IDs to a list of deploy ids to search")
  public Map<String, List<String>> getRequestsAndDeploys() {
    return requestsAndDeploys;
  }

  @Schema(description = "A list of task IDs to search for")
  public List<String> getTaskIds() {
    return taskIds;
  }

  @Schema(description = "Start timestamp (millis, 13 digit)", nullable = true)
  public Optional<Long> getStart() {
    return start;
  }

  @Schema(description = "End timestamp (millis, 13 digit)", nullable = true)
  public Optional<Long> getEnd() {
    return end;
  }

  @Schema(description = "if true, do not query for custom start/end time metadata", defaultValue = "false")
  public boolean isExcludeMetadata() {
    return excludeMetadata;
  }

  @Schema(description = "If true, do not generate download/get urls, only list objects", defaultValue = "false")
  public boolean isListOnly() {
    return listOnly;
  }

  /**
   * NOTE: maxPerPage is not a guaranteed value. It is possible to get as many as (maxPerPage * 2 - 1) results
   * when using the paginated search endpoint
   */
  @Schema(description = "Target number of results to return", nullable = true)
  public Optional<Integer> getMaxPerPage() {
    return maxPerPage;
  }

  @Schema(description = "S3 continuation tokens, return these to Singularity to continue searching subsequent pages of results")
  public Map<String, ContinuationToken> getContinuationTokens() {
    return continuationTokens;
  }

  @Override
  public String toString() {
    return "SingularityS3SearchRequest{" +
        "requestsAndDeploys=" + requestsAndDeploys +
        ", taskIds=" + taskIds +
        ", start=" + start +
        ", end=" + end +
        ", excludeMetadata=" + excludeMetadata +
        ", listOnly=" + listOnly +
        ", maxPerPage=" + maxPerPage +
        ", continuationTokens=" + continuationTokens +
        '}';
  }
}

@@ -486,16 +486,70 @@
 eploys;%0A
+  private final List%3CString%3E fileNamePrefixWhitelist;%0A
   privat
@@ -841,16 +841,625 @@
 okens;%0A%0A
+  public SingularityS3SearchRequest(Map%3CString, List%3CString%3E%3E requestsAndDeploys,%0A                                    List%3CString%3E taskIds,%0A                                    Optional%3CLong%3E start,%0A                                    Optional%3CLong%3E end,%0A                                    boolean excludeMetadata,%0A                                    boolean listOnly,%0A                                    Optional%3CInteger%3E maxPerPage, Map%3CString, ContinuationToken%3E continuationTokens) %7B%0A    this(requestsAndDeploys, null, taskIds, start, end, excludeMetadata, listOnly, maxPerPage, continuationTokens);%0A  %7D%0A%0A
   @JsonC
@@ -1465,17 +1465,16 @@
 Creator%0A
-%0A
   public
@@ -1575,32 +1575,147 @@
 estsAndDeploys,%0A
+                                    @JsonProperty(%22fileNamePrefixWhitelist%22) List%3CString%3E fileNamePrefixWhitelist,%0A
                 
@@ -2454,24 +2454,144 @@
 emptyMap();%0A
+    this.fileNamePrefixWhitelist = fileNamePrefixWhitelist != null ? fileNamePrefixWhitelist : Collections.emptyList();%0A
     this.tas
@@ -3117,32 +3117,212 @@
 ndDeploys;%0A  %7D%0A%0A
+  @Schema(description = %22A whitelist of file name prefixes which should be returned%22)%0A  public List%3CString%3E getFileNamePrefixWhitelist() %7B%0A    return fileNamePrefixWhitelist;%0A  %7D%0A%0A
   @Schema(descri

Allow clients to specify a file name prefix whitelist with their log search request.