package com.castlabs.reactnative.network;

import android.net.Uri;
import android.os.Build;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import com.castlabs.android.network.Response;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;

/**
 * The completable response.
 */
@RequiresApi(api = Build.VERSION_CODES.N)
public class ResponseCompleter {
  private final @NonNull CompletableFuture<Response> future;
  private final @NonNull Response response;

  public final @NonNull String responseId;
  public final @NonNull String playerId;

  /**
   * Creates a completable response.
   *
   * @param playerId the player ID
   * @param response the original response
   */
  public ResponseCompleter(
      final @NonNull String playerId,
      final @NonNull Response response
  ) {
    this.playerId = playerId;
    this.response = response;

    responseId = UUID.randomUUID().toString();
    future =  new CompletableFuture<Response>();
  }

  /**
   * Returns the type of the response.
   *
   * @return the type of the response.
   */
  @NonNull
  public ResourceType getType() {
    switch (response.type) {
      case Response.DATA_TYPE_DRM_PROVISION:
      case Response.DATA_TYPE_DRM_LICENSE:
        // TODO For license response we get DATA_TYPE_DRM_PROVISION
        // Is it correct?
        return ResourceType.DRM_LICENSE;
      default:
        return ResourceType.OTHER;
    }
  }

  @NonNull
  public int getStatus() {
    return response.responseCode;
  }

  @NonNull
  public Uri getUrl() {
    return response.uri;
  }

  @NonNull
  public Map<String, List<String>> getHeaders() {
    return response.headers;
  }

  @Nullable
  public byte[] getBody() {
    return response.getData();
  }

  public void setHeaders(
      final @NonNull Map<String, List<String>> headers
  ) {
    response.headers.clear();
    response.headers.putAll(headers);
  }

  public void setBody(
      final @NonNull byte[] body
  ) {
    response.setData(body);
  }

  @NonNull
  public Future<Response> getCompleted() {
    return future;
  }

  public void complete() {
    future.complete(response);
  }
}
