package com.filestack.util;

import com.filestack.responses.CompleteResponse;
import com.filestack.responses.StartResponse;
import com.filestack.responses.StoreResponse;
import com.filestack.responses.UploadResponse;
import com.google.gson.JsonObject;
import java.util.Map;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;

/** Combines all REST services into a single service. */
public class FsService implements FsApiService, FsCdnService, FsUploadService, FsCloudService {
  private FsApiService customApiService;
  private FsCdnService customCdnService;
  private FsUploadService customUploadService;
  private FsCloudService customCloudService;

  /** Constructs instance using singleton REST services. */
  public FsService() { }

  /** Constructs instance using custom REST services. */
  public FsService(FsApiService api, FsCdnService cdn, FsUploadService upload,
                   FsCloudService cloud) {
    this.customApiService = api;
    this.customCdnService = cdn;
    this.customUploadService = upload;
    this.customCloudService = cloud;
  }
  
  private FsApiService getApiService() {
    if (customApiService != null) {
      return customApiService;
    } else {
      return Networking.getFsApiService();
    }
  }

  private FsCdnService getCdnService() {
    if (customCdnService != null) {
      return customCdnService;
    } else {
      return Networking.getFsCdnService();
    }
  }

  private FsUploadService getUploadService() {
    if (customUploadService != null) {
      return customUploadService;
    } else {
      return Networking.getFsUploadService();
    }
  }

  private FsCloudService getCloudService() {
    if (customCloudService != null) {
      return customCloudService;
    } else {
      return Networking.getFsCloudService();
    }
  }

  @Override
  public Call<ResponseBody> overwrite(String handle, String policy, String signature,
                                      RequestBody body) {
    return getApiService().overwrite(handle, policy, signature, body);
  }

  @Override
  public Call<ResponseBody> delete(String handle, String key, String policy, String signature) {
    return getApiService().delete(handle, key, policy, signature);
  }

  @Override
  public Call<ResponseBody> get(String handle, String policy, String signature) {
    return getCdnService().get(handle, policy, signature);
  }

  @Override
  public Call<ResponseBody> transform(String tasks, String handle) {
    return getCdnService().transform(tasks, handle);
  }

  @Override
  public Call<JsonObject> transformDebug(String tasks, String handle) {
    return getCdnService().transformDebug(tasks, handle);
  }

  @Override
  public Call<StoreResponse> transformStore(String tasks, String handle) {
    return getCdnService().transformStore(tasks, handle);
  }

  @Override
  public Call<ResponseBody> transformExt(String key, String tasks, String url) {
    return getCdnService().transformExt(key, tasks, url);
  }

  @Override
  public Call<JsonObject> transformDebugExt(String key, String tasks, String url) {
    return getCdnService().transformDebugExt(key, tasks, url);
  }

  @Override
  public Call<StoreResponse> transformStoreExt(String key, String tasks, String url) {
    return getCdnService().transformStoreExt(key, tasks, url);
  }

  @Override
  public Call<StartResponse> start(Map<String, RequestBody> parameters) {
    return getUploadService().start(parameters);
  }

  @Override
  public Call<UploadResponse> upload(Map<String, RequestBody> parameters) {
    return getUploadService().upload(parameters);
  }

  @Override
  public Call<ResponseBody> uploadS3(Map<String, String> headers, String url, RequestBody body) {
    return getUploadService().uploadS3(headers, url, body);
  }

  @Override
  public Call<ResponseBody> commit(Map<String, RequestBody> parameters) {
    return getUploadService().commit(parameters);
  }

  @Override
  public Call<CompleteResponse> complete(Map<String, RequestBody> parameters) {
    return getUploadService().complete(parameters);
  }

  @Override
  public Call<JsonObject> prefetch(JsonObject body) {
    return getCloudService().prefetch(body);
  }

  @Override
  public Call<JsonObject> list(JsonObject body) {
    return getCloudService().list(body);
  }

  @Override
  public Call<JsonObject> store(JsonObject body) {
    return getCloudService().store(body);
  }
}

@@ -432,80 +432,149 @@
 ice 
-implements FsApiService, FsCdnService, FsUploadService, FsCloudService %7B
+%7B%0A  // An instance of this class can hold individual custom services%0A  // It doesn't contain singletons though, so we specify these as custom
 %0A  p
@@ -1158,30 +1158,29 @@
 ;%0A  %7D%0A  %0A  p
-rivate
+ublic
  FsApiServic
@@ -1181,29 +1181,19 @@
 Service 
-getApiService
+api
 () %7B%0A   
@@ -1322,30 +1322,29 @@
   %7D%0A  %7D%0A%0A  p
-rivate
+ublic
  FsCdnServic
@@ -1345,29 +1345,19 @@
 Service 
-getCdnService
+cdn
 () %7B%0A   
@@ -1486,30 +1486,29 @@
   %7D%0A  %7D%0A%0A  p
-rivate
+ublic
  FsUploadSer
@@ -1512,32 +1512,22 @@
 Service 
-getU
+u
 pload
-Service
 () %7B%0A   
@@ -1665,30 +1665,29 @@
   %7D%0A  %7D%0A%0A  p
-rivate
+ublic
  FsCloudServ
@@ -1690,31 +1690,21 @@
 Service 
-getCloudService
+cloud
 () %7B%0A   
@@ -1821,32 +1821,32 @@
 CloudService();%0A
+
     %7D%0A  %7D%0A%0A  @Ov
@@ -1842,2583 +1842,7 @@
 %0A  %7D
-%0A%0A  @Override%0A  public Call%3CResponseBody%3E overwrite(String handle, String policy, String signature,%0A                                      RequestBody body) %7B%0A    return getApiService().overwrite(handle, policy, signature, body);%0A  %7D%0A%0A  @Override%0A  public Call%3CResponseBody%3E delete(String handle, String key, String policy, String signature) %7B%0A    return getApiService().delete(handle, key, policy, signature);%0A  %7D%0A%0A  @Override%0A  public Call%3CResponseBody%3E get(String handle, String policy, String signature) %7B%0A    return getCdnService().get(handle, policy, signature);%0A  %7D%0A%0A  @Override%0A  public Call%3CResponseBody%3E transform(String tasks, String handle) %7B%0A    return getCdnService().transform(tasks, handle);%0A  %7D%0A%0A  @Override%0A  public Call%3CJsonObject%3E transformDebug(String tasks, String handle) %7B%0A    return getCdnService().transformDebug(tasks, handle);%0A  %7D%0A%0A  @Override%0A  public Call%3CStoreResponse%3E transformStore(String tasks, String handle) %7B%0A    return getCdnService().transformStore(tasks, handle);%0A  %7D%0A%0A  @Override%0A  public Call%3CResponseBody%3E transformExt(String key, String tasks, String url) %7B%0A    return getCdnService().transformExt(key, tasks, url);%0A  %7D%0A%0A  @Override%0A  public Call%3CJsonObject%3E transformDebugExt(String key, String tasks, String url) %7B%0A    return getCdnService().transformDebugExt(key, tasks, url);%0A  %7D%0A%0A  @Override%0A  public Call%3CStoreResponse%3E transformStoreExt(String key, String tasks, String url) %7B%0A    return getCdnService().transformStoreExt(key, tasks, url);%0A  %7D%0A%0A  @Override%0A  public Call%3CStartResponse%3E start(Map%3CString, RequestBody%3E parameters) %7B%0A    return getUploadService().start(parameters);%0A  %7D%0A%0A  @Override%0A  public Call%3CUploadResponse%3E upload(Map%3CString, RequestBody%3E parameters) %7B%0A    return getUploadService().upload(parameters);%0A  %7D%0A%0A  @Override%0A  public Call%3CResponseBody%3E uploadS3(Map%3CString, String%3E headers, String url, RequestBody body) %7B%0A    return getUploadService().uploadS3(headers, url, body);%0A  %7D%0A%0A  @Override%0A  public Call%3CResponseBody%3E commit(Map%3CString, RequestBody%3E parameters) %7B%0A    return getUploadService().commit(parameters);%0A  %7D%0A%0A  @Override%0A  public Call%3CCompleteResponse%3E complete(Map%3CString, RequestBody%3E parameters) %7B%0A    return getUploadService().complete(parameters);%0A  %7D%0A%0A  @Override%0A  public Call%3CJsonObject%3E prefetch(JsonObject body) %7B%0A    return getCloudService().prefetch(body);%0A  %7D%0A%0A  @Override%0A  public Call%3CJsonObject%3E list(JsonObject body) %7B%0A    return getCloudService().list(body);%0A  %7D%0A%0A  @Override%0A  public Call%3CJsonObject%3E store(JsonObject body) %7B%0A    return getCloudService().store(body);%0A  %7D
 %0A%7D%0A

Remove interface implementations from FsService