package com.castlabs.reactnative.network;

import android.os.Build;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import com.castlabs.android.network.Request;
import com.castlabs.android.network.RequestModifier;
import com.castlabs.android.network.Response;
import com.castlabs.reactnative.utils.DrmEventEmitter;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * The asynchronous request modifier.
 */
@RequiresApi(api = Build.VERSION_CODES.N)
public class DeferredRequestModifier implements RequestModifier {
  private final @NonNull DrmEventEmitter drmEventEmitter;
  private final @NonNull Map<String, RequestCompleter> requestCompleterCache;
  private final @NonNull String playerId;

  /**
   * Creates the request modifier.
   *
   * @param drmEventEmitter the global event emitter
   * @param requestCompleterCache the global request completer cache
   * @param playerId the player ID
   */
  public DeferredRequestModifier(
      @NonNull final DrmEventEmitter drmEventEmitter,
      @NonNull final Map<String, RequestCompleter> requestCompleterCache,
      @NonNull final String playerId
  ) {
    this.drmEventEmitter = drmEventEmitter;
    this.requestCompleterCache = requestCompleterCache;
    this.playerId = playerId;
  }

  @NonNull
  @Override
  public Request onRequest(final @NonNull Request request) {

    if (request.type != Request.DATA_TYPE_DRM_LICENSE
        && request.type != Response.DATA_TYPE_DRM_PROVISION) {
      return request;
    }

    if ( "www.googleapis.com".equals(request.getUri().getHost())) {
      // ignore requests to Google API, for example:
      // https://www.googleapis.com/certificateprovisioning
      return request;
    }

    final RequestCompleter requestCompleter = new RequestCompleter(playerId, request);
    requestCompleterCache.put(requestCompleter.requestId, requestCompleter);

    drmEventEmitter.emitNewRequest(
        playerId,
        requestCompleter.requestId,
        requestCompleter.getType(),
        requestCompleter.getMethod(),
        requestCompleter.getUrl(),
        requestCompleter.getHeaders(),
        requestCompleter.getBody()
    );

    try {
      Request req = requestCompleter.getCompleted().get();
      Log.w("DeferredRequestModifier", "Got: "+req);
      return req;
    } catch (ExecutionException | InterruptedException e) {
      Log.w("DeferredRequestModifier", "Error: "+e);
      throw new RuntimeException(e);
    }
  }
}
