package com.heroku;

import com.atlassian.bamboo.build.logger.BuildLogger;
import com.atlassian.bamboo.configuration.ConfigurationMapImpl;
import com.atlassian.bamboo.task.TaskContext;
import com.atlassian.bamboo.task.TaskResult;
import com.atlassian.bamboo.task.TaskState;
import com.atlassian.bamboo.task.TaskType;
import org.jmock.Mock;
import org.jmock.MockObjectTestCase;
import org.jmock.core.InvocationMatcher;
import org.jmock.core.matcher.AnyArgumentsMatcher;

import java.io.File;

public class ArtifactDeploymentTasksTest extends MockObjectTestCase {

    private final Mock mockStatics = new Mock(WarDeploymentTask.StaticSandbox.class);
    private final Mock mockContext = new Mock(TaskContext.class);
    private final Mock mockLogger = new Mock(BuildLogger.class);
    private final Mock mockSuccessfulTaskResult = new Mock(TaskResult.class);
    private final Mock mockFailedTaskResult = new Mock(TaskResult.class);
    private final ConfigurationMapImpl configMap = new ConfigurationMapImpl();

    @Override
    protected void setUp() throws Exception {
        super.setUp();

        mockStatics.expects(anything()).method("success").will(returnValue(mockSuccessfulTaskResult.proxy()));
        mockStatics.expects(anything()).method("failed").will(returnValue(mockFailedTaskResult.proxy()));
        mockContext.expects(once()).method("getBuildLogger").will(returnValue(mockLogger.proxy()));
        mockContext.expects(atLeastOnce()).method("getConfigurationMap").will(returnValue(configMap));
        mockContext.expects(atLeastOnce()).method("getWorkingDirectory").will(returnValue(new File(System.getProperty("heroku.workingDir"))));
        mockLogger.expects(anything()).method("addBuildLogEntry");
        mockLogger.expects(anything()).method("addErrorLogEntry");
        mockSuccessfulTaskResult.expects(anything()).method("getTaskState").will(returnValue(TaskState.SUCCESS));
        mockFailedTaskResult.expects(anything()).method("getTaskState").will(returnValue(TaskState.FAILED));
    }
    
    protected TaskResult runTask(Class<? extends AbstractDeploymentTask> taskClass, Class<? extends AbstractDeploymentTaskConfigurator> configuratorClass) throws Exception {
        configMap.put("apiKey", System.getProperty("heroku.apiKey"));
        configMap.put("appName", System.getProperty("heroku.appName"));
        TaskType task = taskClass.getConstructor(AbstractDeploymentTask.StaticSandbox.class).newInstance((AbstractDeploymentTask.StaticSandbox) mockStatics.proxy());
        return task.execute((TaskContext) mockContext.proxy());
    }
    
    public void testWarDeployment() throws Exception {
        configMap.put("war", System.getProperty("heroku.warFile"));
        assertEquals(TaskState.SUCCESS, runTask(WarDeploymentTask.class, WarDeploymentTaskConfigurator.class).getTaskState());
    }

    public void testFatJarDeployment() throws Exception {
        configMap.put("jar", System.getProperty("heroku.jarFile"));
        configMap.put("procfile", System.getProperty("heroku.procfileFile"));
        assertEquals(TaskState.SUCCESS, runTask(FatJarDeploymentTask.class, FatJarDeploymentTaskConfigurator.class).getTaskState());
    }

    public void testTarGzDeployment() throws Exception {
        configMap.put("targz", System.getProperty("heroku.targzFile"));
        configMap.put("procfile", System.getProperty("heroku.procfileFile"));
        assertEquals(TaskState.SUCCESS, runTask(TarGzDeploymentTask.class, TargGzDeploymentTaskConfigurator.class).getTaskState());
    }

    InvocationMatcher anything() {
        return new AnyArgumentsMatcher();
    }
}

@@ -483,16 +483,110 @@
 io.File;
+%0Aimport java.io.FileNotFoundException;%0Aimport java.io.IOException;%0Aimport java.io.PrintWriter;
 %0A%0Apublic
@@ -1097,16 +1097,69 @@
 pImpl();
+%0A    private final File workingDir = createTempDir();
 %0A%0A    @O
@@ -1750,44 +1750,8 @@
 lue(
-new File(System.getProperty(%22heroku.
 work
@@ -1756,19 +1756,16 @@
 rkingDir
-%22))
 ));%0A    
@@ -2773,43 +2773,64 @@
 r%22, 
-System.getProperty(%22heroku.warFile%22
+File.createTempFile(%22some%22, %22.war%22, workingDir).getName(
 ));%0A
@@ -3054,121 +3054,137 @@
 r%22, 
-System.getProperty(%22heroku.jarFile%22));%0A        configMap.put(%22procfile%22, System.getProperty(%22heroku.procfileFile%22
+File.createTempFile(%22some%22, %22.jar%22, workingDir).getName());%0A        configMap.put(%22procfile%22, createProcfile(workingDir).getName(
 ));%0A
@@ -3415,45 +3415,67 @@
 z%22, 
-System.getProperty(%22heroku
+File.createTempFile(%22some%22, %22
 .tar
+.
 gz
-File%22
+%22, workingDir).getName(
 ));%0A
@@ -3512,48 +3512,43 @@
 e%22, 
-System.getProperty(%22heroku.procfileFile%22
+createProcfile(workingDir).getName(
 ));%0A
@@ -3721,16 +3721,16 @@
 ing() %7B%0A
-
         
@@ -3769,10 +3769,875 @@
 ;%0A    %7D%0A
+    %0A    private static File createTempDir() %7B%0A        try %7B%0A            final File tmp = File.createTempFile(%22temp%22, %22dir%22);%0A            if (!tmp.delete()) throw new IOException(%22Could not delete%22);%0A            if (!tmp.mkdir()) throw new IOException(%22Could not mkdir%22);%0A            return tmp;%0A        %7D catch (IOException e) %7B%0A            throw new RuntimeException(e);%0A        %7D%0A    %7D%0A    %0A    private File createProcfile(File dir) %7B%0A        try %7B%0A            final File procfile = File.createTempFile(%22Procfile%22, %22%22, dir);%0A            PrintWriter writer = new PrintWriter(procfile);%0A            writer.append(%22web: exit%22);%0A            writer.close();%0A            return procfile;%0A        %7D catch (FileNotFoundException e) %7B%0A            throw new RuntimeException(e);%0A        %7D catch (IOException e) %7B%0A            throw new RuntimeException(e);%0A        %7D%0A    %7D%0A
 %7D%0A

remove dependency on local file for tests