package model;

import okhttp3.HttpUrl;
import util.FilestackService;
import util.Networking;

import java.util.ArrayList;
import java.util.Arrays;

/**
 * Base class for file transformations and conversions.
 */
public class Transform {
    String apiKey;
    String source;

    ArrayList<Task> tasks;

    FilestackService.Process processService;

    Transform(Client client, String source) {
        this(client, source, null);
    }

    Transform(FileLink fileLink) {
        this(null, null, fileLink);
    }

    Transform(Client client, String source, FileLink fileLink) {
        if (client != null) {
            this.apiKey = client.getApiKey();
            this.source = source;
        } else {
            this.source = fileLink.getHandle();
        }

        this.tasks = new ArrayList<>();
        this.processService = Networking.getProcessService();

        Security security = client != null ? client.getSecurity() : fileLink.getSecurity();
        if (security != null) {
            Task securityTask = new Task("security");
            securityTask.addOption("policy", security.getPolicy());
            securityTask.addOption("signature", security.getSignature());
            this.tasks.add(securityTask);
        }
    }

    /**
     * Generic task object.
     * A "task" in this case is a transformation, for example resize, crop, convert, etc.
     */
    protected static class Task {
        String name;
        ArrayList<Option> options;

        Task(String name) {
            this.name = name;
            this.options = new ArrayList<>();
        }

        void addOption(String key, Object value) {
            addOption(key, value.toString());
        }

        void addOption(String key, Object value[]) {
            String valueString = Arrays.toString(value);
            // Remove spaces between array items
            valueString = valueString.replace(" ", "");
            addOption(key, valueString);
        }

        void addOption(String key, String value) {
            options.add(new Option(key, value));
        }

        @Override
        public String toString() {
            StringBuilder stringBuilder = new StringBuilder(name);
            stringBuilder.append("=");
            for (Option option : options)
                if (option.value != null)
                    stringBuilder.append(option.key).append(":").append(option.value).append(",");
            stringBuilder.deleteCharAt(stringBuilder.length()-1);
            return stringBuilder.toString();
        }
    }

    /**
     * Each {@link Task Task} object has options.
     * These are the settings for that task.
     * For example the resize task would have options for width and height.
     */
    protected static class Option {
        String key;
        String value;

        Option(String key, String value) {
            this.key = key;
            this.value = value;
        }
    }

    /**
     * Build tasks into single string to insert into request.
     */
    protected String getTasksString() {
        if (tasks.size() == 0)
            return "";

        StringBuilder stringBuilder = new StringBuilder();
        for (Task task : tasks)
            stringBuilder.append(task.toString()).append('/');
        stringBuilder.deleteCharAt(stringBuilder.length()-1);
        return stringBuilder.toString();
    }

    public String url() {
        String tasksString = getTasksString();

        if (apiKey != null) {
            // TODO Implement when we add external transforms
            return null;
        } else {
            HttpUrl httpUrl = processService.get(tasksString, source).request().url();
            String urlString = httpUrl.toString();
            // When forming the request we add a / between tasks, then add that entire string as a path variable
            // Because it's added as a single path variable, the / is URL encoded
            // That's a little confusing so we're replacing "%2F" with "/" for a more expected URL
            return urlString.replace("%2F", "/");
        }
    }
}

@@ -3435,16 +3435,41 @@
 tring();
+%0A        HttpUrl httpUrl;
 %0A%0A      
@@ -3481,34 +3481,32 @@
 (apiKey != null)
- %7B
 %0A            // 
@@ -3506,81 +3506,89 @@
     
-// TODO Implement when we add external transforms%0A            return null
+httpUrl = processService.getExternal(apiKey, tasksString, source).request().url()
 ;%0A  
@@ -3588,33 +3588,29 @@
 l();%0A       
- %7D
  else
- %7B
 %0A           
@@ -3606,32 +3606,24 @@
             
-HttpUrl 
 httpUrl = pr
@@ -3681,63 +3681,9 @@
 ();%0A
-            String urlString = httpUrl.toString();%0A    
+%0A
     
@@ -3795,20 +3795,16 @@
         
-    
 // Becau
@@ -3873,20 +3873,16 @@
         
- 
-   
 // That'
@@ -3972,28 +3972,33 @@
     
-    
 return 
-url
+httpUrl.to
 String
+()
 .rep
@@ -4015,26 +4015,16 @@
 , %22/%22);%0A
-        %7D%0A
     %7D%0A%7D%0A

Update Transform url method for external transforms