package com.filestack;

import com.filestack.transforms.ImageTransform;
import com.filestack.util.Upload;

import io.reactivex.Single;
import io.reactivex.schedulers.Schedulers;

import java.io.IOException;
import java.util.concurrent.Callable;

/**
 * Uploads new files.
 */
public class FilestackClient {
  private String apiKey;
  private Security security;

  /**
   * Constructs an instance without security.
   *
   * @param apiKey account key from the dev portal
   */
  public FilestackClient(String apiKey) {
    this.apiKey = apiKey;
  }

  /**
   * Constructs an instance with security.
   *
   * @param apiKey   account key from the dev portal
   * @param security needs required permissions for your intended actions
   */
  public FilestackClient(String apiKey, Security security) {
    this.apiKey = apiKey;
    this.security = security;
  }

  /**
   * Upload local file to Filestack using default storage options.
   *
   * @param filepath path to the file, can be local or absolute
   * @return new {@link FileLink} referencing file
   * @throws IOException for network failures or invalid security
   */
  public FileLink upload(String filepath) throws IOException {
    UploadOptions defaultOptions = new UploadOptions.Builder().build();
    return upload(filepath, defaultOptions);
  }

  /**
   * Upload local file to Filestack using custom storage options.
   *
   * @param filepath path to the file, can be local or absolute
   * @param options storage options, https://www.filestack.com/docs/rest-api/store
   * @return new {@link FileLink} referencing file
   * @throws IOException or network failures or invalid security
   */
  public FileLink upload(String filepath, UploadOptions options) throws IOException {
    Upload upload = new Upload(filepath, this, options);
    return upload.run();
  }

  // Async method wrappers

  /**
   * Async, observable version of {@link #upload(String)}.
   * Throws same exceptions.
   */
  public Single<FileLink> uploadAsync(String filepath) {
    UploadOptions defaultOptions = new UploadOptions.Builder().build();
    return uploadAsync(filepath, defaultOptions);
  }

  /**
   * Async, observable version of {@link #upload(String, UploadOptions)}.
   * Throws same exceptions.
   */
  public Single<FileLink> uploadAsync(final String filepath, final UploadOptions options) {
    return Single.fromCallable(new Callable<FileLink>() {
      @Override
      public FileLink call() throws IOException {
        return upload(filepath, options);
      }
    })
        .subscribeOn(Schedulers.io())
        .observeOn(Schedulers.single());
  }

  /**
   * Creates an image transformation object for this file.
   * A transformation call isn't made directly by this method.
   *
   * @return {@link ImageTransform ImageTransform} instance configured for this file
   */
  public ImageTransform imageTransform(String url) {
    return new ImageTransform(this, url);
  }

  public String getApiKey() {
    return apiKey;
  }

  public Security getSecurity() {
    return security;
  }
}

@@ -17,16 +17,221 @@
 stack;%0A%0A
+import com.filestack.errors.InternalException;%0Aimport com.filestack.errors.InvalidParameterException;%0Aimport com.filestack.errors.PolicySignatureException;%0Aimport com.filestack.errors.ValidationException;%0A
 import c
@@ -1142,32 +1142,32 @@
    * @param 
-file
 path
+name
  path to the
@@ -1266,118 +1266,592 @@
 ows 
-IOException for network failures or invalid security%0A   */%0A  public FileLink upload(String filepath) throws IO
+ValidationException       if the pathname doesn't exist or isn't a regular file%0A   * @throws IOException               if request fails because of network or other IO issue%0A   * @throws PolicySignatureException  if policy and/or signature are invalid or inadequate%0A   * @throws InvalidParameterException if a request parameter is missing or invalid%0A   * @throws InternalException         if unexpected error occurs%0A   */%0A  public FileLink upload(String pathname)%0A      throws ValidationException, IOException, PolicySignatureException,%0A             InvalidParameterException, Internal
 Exce
@@ -1948,24 +1948,24 @@
  upload(
-file
 path
+name
 , defaul
@@ -2069,24 +2069,24 @@
  @param 
-file
 path
+name
  path to
@@ -2141,16 +2141,17 @@
 options 
+ 
 storage 
@@ -2273,59 +2273,422 @@
 ows 
-IOException or network failures or invalid security
+ValidationException       if the pathname doesn't exist or isn't a regular file%0A   * @throws IOException               if request fails because of network or other IO issue%0A   * @throws PolicySignatureException  if policy and/or signature are invalid or inadequate%0A   * @throws InvalidParameterException if a request parameter is missing or invalid%0A   * @throws InternalException         if unexpected error occurs
 %0A   
@@ -2722,24 +2722,24 @@
 (String 
-file
 path
+name
 , Upload
@@ -2754,24 +2754,30 @@
 options)
+%0A     
  throws 
 IOExcept
@@ -2760,34 +2760,140 @@
 s)%0A      throws 
-IO
+ValidationException, IOException, PolicySignatureException,%0A             InvalidParameterException, Internal
 Exception %7B%0A    
@@ -2919,24 +2919,24 @@
  Upload(
-file
 path
+name
 , this, 
@@ -3069,32 +3069,25 @@
 ing)%7D.%0A   * 
-Throws s
+S
 ame exceptio
@@ -3080,32 +3080,62 @@
  Same exceptions
+ are passed through observable
 .%0A   */%0A  public
@@ -3399,16 +3399,9 @@
   * 
-Throws s
+S
 ame 
@@ -3406,24 +3406,54 @@
 e exceptions
+ are passed through observable
 .%0A   */%0A  pu
@@ -3646,26 +3646,24 @@
 ll() throws 
-IO
 Exception %7B%0A
@@ -3829,23 +3829,29 @@
  an 
-i
+%7B@link I
 mage
- t
+T
 ransform
 atio
@@ -3846,21 +3846,17 @@
 ransform
-ation
+%7D
  object 

Update FilestackClient with new exception classes