package org.jenkinsci.plugins.ewm.actions;

import hudson.model.Run;
import jenkins.model.RunAction2;
import org.jenkinsci.plugins.ewm.Messages;
import org.jenkinsci.plugins.ewm.model.ExternalWorkspace;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * {@link RunAction2} implementation for the {@link org.jenkinsci.plugins.ewm.steps.ExwsAllocateStep}.
 * Stores the allocated {@link ExternalWorkspace}(s) that will be later used by the downstream job.
 *
 * @author Alexandru Somai
 */
public class ExwsAllocateActionImpl implements RunAction2 {

    private final List<ExternalWorkspace> allocatedWorkspaces = new LinkedList<>();
    private Run parent;

    @Restricted(NoExternalUse.class)
    public Run getParent() {
        return parent;
    }

    public void addAllocatedWorkspace(ExternalWorkspace externalWorkspace) {
        allocatedWorkspaces.add(externalWorkspace);
    }

    @Nonnull
    public List<ExternalWorkspace> getAllocatedWorkspaces() {
        return Collections.unmodifiableList(allocatedWorkspaces);
    }

    @Override
    public String getIconFileName() {
        // TODO change with an appropriate icon file
        return "folder.png";
    }

    @Override
    public String getDisplayName() {
        return Messages.actions_ExwsAllocateAction_DisplayName();
    }

    @Override
    public String getUrlName() {
        return "exwsAllocate";
    }

    @Override
    public void onAttached(Run<?, ?> run) {
        this.parent = run;
    }

    @Override
    public void onLoad(Run<?, ?> run) {
        this.parent = run;
    }

    @SuppressWarnings("unused")
    public ExternalWorkspace getDynamic(String token) {
        return getExternalWorkspaceById(token);
    }

    /**
     * Returns the {@link ExternalWorkspace} that has the id equal to the given {@code id}.
     * Returns {@code null} if none was found.
     *
     * @param id the external workspace id
     * @return the external workspace whose id matches the given token, {@code null} otherwise
     */
    @CheckForNull
    private ExternalWorkspace getExternalWorkspaceById(String id) {
        // TODO use transient map to cache workspaces by id
        for (ExternalWorkspace allocatedWorkspace : allocatedWorkspaces) {
            if (allocatedWorkspace == null) {
                // be defensive
                continue;
            }
            if (allocatedWorkspace.getId().equals(id)) {
                return allocatedWorkspace;
            }
        }

        return null;
    }
}

@@ -390,16 +390,42 @@
 ctions;%0A
+import java.util.HashMap;%0A
 import j
@@ -467,16 +467,38 @@
 il.List;
+%0Aimport java.util.Map;
 %0A%0A/**%0A *
@@ -902,16 +902,85 @@
 arent;%0A%0A
+    private transient Map%3CString, ExternalWorkspace%3E workspacesMap;%0A%0A
     @Res
@@ -1105,16 +1105,25 @@
 rkspace(
+@Nonnull 
 External
@@ -2431,111 +2431,60 @@
     
-// TODO use transient map to cache workspaces by id%0A        for (ExternalWorkspace allocatedWorkspace :
+if (workspacesMap == null %7C%7C workspacesMap.size() !=
  all
@@ -2499,16 +2499,23 @@
 rkspaces
+.size()
 ) %7B%0A    
@@ -2522,38 +2522,25 @@
         
-if (allocatedW
+w
 orkspace
  == null
@@ -2535,190 +2535,164 @@
 pace
+sMap
  =
-=
  n
-ull) %7B%0A                // be defensive%0A                continue;%0A            %7D%0A            if (allocatedWorkspace.getId().equals(id)) %7B%0A                return allocatedW
+ew HashMap%3C%3E();%0A            for (ExternalWorkspace workspace : allocatedWorkspaces) %7B%0A                workspacesMap.put(workspace.getId(), w
 orkspace
 ;%0A  
@@ -2687,16 +2687,17 @@
 orkspace
+)
 ;%0A      
@@ -2730,20 +2730,37 @@
  return 
-null
+workspacesMap.get(id)
 ;%0A    %7D%0A

Index allocated workspaces by id