package org.jenkinsci.plugins.runselector.steps;

import hudson.model.Result;
import hudson.model.queue.QueueTaskFuture;
import org.apache.commons.lang.RandomStringUtils;
import org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition;
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import org.jenkinsci.plugins.workflow.job.WorkflowRun;
import org.junit.ClassRule;
import org.junit.Test;
import org.jvnet.hudson.test.BuildWatcher;
import org.jvnet.hudson.test.JenkinsRule;

import static java.lang.String.format;
import static org.hamcrest.Matchers.notNullValue;
import static org.junit.Assert.assertThat;

/**
 * Tests for the {@link RunSelectorStep}.
 *
 * @author Alexandru Somai
 */
public class RunSelectorStepTest {

    @ClassRule
    public static JenkinsRule j = new JenkinsRule();

    @ClassRule
    public static BuildWatcher watcher = new BuildWatcher();

    @Test
    public void missingProjectName() throws Exception {
        WorkflowRun run = createWorkflowJobAndRun("def runWrapper = runSelector projectName: '' ");

        j.assertBuildStatus(Result.FAILURE, run);
        j.assertLogContains("ERROR: Project Name parameter not provided", run);
    }

    @Test
    public void missingProject() throws Exception {
        WorkflowRun run = createWorkflowJobAndRun("def runWrapper = runSelector projectName: 'not-existent' ");

        j.assertBuildStatus(Result.FAILURE, run);
        j.assertLogContains("ERROR: Unable to find project named: not-existent. This may be due to incorrect project name or permission settings", run);
    }

    @Test
    public void usingDefaultSelectorAndFilter() throws Exception {
        WorkflowRun upstreamRun = createWorkflowJobAndRun("echo 'foobar'");
        String projectName = upstreamRun.getParent().getFullName();
        j.assertBuildStatusSuccess(upstreamRun);

        WorkflowRun run = createWorkflowJobAndRun(format("" +
                "def runWrapper = runSelector projectName: '%s' \n" +
                "echo 'Selected run: ' + runWrapper.displayName", projectName));

        j.assertBuildStatusSuccess(run);
        j.assertLogContains("Run Selector was not provided, using the default one: Latest specific status build (Stable)", run);
        j.assertLogContains("Run Filter was not provided", run);
        j.assertLogContains("Selected run: #1", run);
    }

    @Test
    public void upstreamHasNoLastStableBuild() throws Exception {
        WorkflowRun upstreamRun = createWorkflowJobAndRun("throw new Exception()");
        String projectName = upstreamRun.getParent().getFullName();
        j.assertBuildStatus(Result.FAILURE, upstreamRun);

        WorkflowRun run = createWorkflowJobAndRun(format("def runWrapper = runSelector projectName: '%s' ", projectName));

        j.assertBuildStatus(Result.FAILURE, run);
        j.assertLogContains("Run Selector was not provided, using the default one: Latest specific status build (Stable)", run);
        j.assertLogContains("Run Filter was not provided", run);
        j.assertLogContains(format("ERROR: Unable to find Run for: %s, with selector: Latest specific status build (Stable) and filter: No Filter", projectName), run);
    }

    @Test
    public void specificBuildNumberDoesNotExist() throws Exception {
        WorkflowRun upstreamRun = createWorkflowJobAndRun("echo 'foobar'");
        String projectName = upstreamRun.getParent().getFullName();
        j.assertBuildStatusSuccess(upstreamRun);

        WorkflowRun run = createWorkflowJobAndRun(format("" +
                "def runWrapper = runSelector projectName: '%s', " +
                "selector: [$class: 'SpecificRunSelector', buildNumber: '-1'], " +
                "verbose: true", projectName));

        j.assertBuildStatus(Result.FAILURE, run);
        j.assertLogContains(format("no such build -1 in %s", projectName), run);
        j.assertLogContains(format("ERROR: Unable to find Run for: %s, with selector: Specific build and filter: No Filter", projectName), run);
    }

    private WorkflowRun createWorkflowJobAndRun(String script) throws Exception {
        WorkflowJob job = j.jenkins.createProject(WorkflowJob.class, RandomStringUtils.randomAlphanumeric(7));
        job.setDefinition(new CpsFlowDefinition(script));
        QueueTaskFuture<WorkflowRun> runFuture = job.scheduleBuild2(0);
        assertThat(runFuture, notNullValue());

        return runFuture.get();
    }
}

@@ -335,16 +335,65 @@
 lowRun;%0A
+import org.junit.After;%0Aimport org.junit.Before;%0A
 import o
@@ -412,16 +412,16 @@
 ssRule;%0A
-
 import o
@@ -519,16 +519,85 @@
 insRule;
+%0Aimport org.jvnet.localizer.LocaleProvider;%0A%0Aimport java.util.Locale;
 %0A%0Aimport
@@ -915,32 +915,32 @@
 %0A    @ClassRule%0A
-
     public stati
@@ -981,24 +981,491 @@
 Watcher();%0A%0A
+    private LocaleProvider providerToRestore;%0A%0A    @Before%0A    public void setUp() %7B%0A        providerToRestore = LocaleProvider.getProvider();%0A%0A        // expect English messages%0A        LocaleProvider.setProvider(new LocaleProvider() %7B%0A            @Override%0A            public Locale get() %7B%0A                return Locale.ENGLISH;%0A            %7D%0A        %7D);%0A    %7D%0A%0A    @After%0A    public void tearDown() %7B%0A        LocaleProvider.setProvider(providerToRestore);%0A    %7D%0A%0A
     @Test%0A  

Set LocaleProvider for RunSelectorStepTest