package org.datadog.jenkins.plugins.datadog;

import hudson.EnvVars;
import hudson.model.Job;
import hudson.model.Result;
import hudson.model.Run;
import hudson.model.TaskListener;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import java.io.IOException;
import java.util.HashMap;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.*;

@RunWith(PowerMockRunner.class)
@PrepareForTest({DatadogHttpRequests.class, DatadogUtilities.class})
public class DatadogBuildListenerTest {

    private DatadogBuildListener datadogBuildListener;

    @Before
    public void setUp() throws Exception {
        datadogBuildListener = spy(new DatadogBuildListener());

        PowerMockito.mockStatic(DatadogUtilities.class);
        when(DatadogUtilities.isJobTracked(anyString())).thenReturn(true);
        when(DatadogUtilities.assembleTags(any(JSONObject.class), any(HashMap.class))).thenReturn(new JSONArray());

        PowerMockito.mockStatic(DatadogHttpRequests.class);

        doReturn(descriptor()).when(datadogBuildListener).getDescriptor();
    }



    @Test
    public void onCompleted_duration_fromRun() throws Exception {
        Run run = run();
        when(run.getDuration()).thenReturn(123000L);

        datadogBuildListener.onCompleted(run, mock(TaskListener.class));

        JSONObject series = capturePostMetricRequestPayload();
        assertEquals("jenkins.job.duration", series.getString("metric"));
        assertEquals(123L, valueOfFirstPoint(series), 0);
    }

    @Test
    public void onCompleted_duration_computedFromFallbackForPipelineJobs() throws Exception {
        Run run = run();
        when(run.getDuration()).thenReturn(0L); // pipeline jobs always return 0

        datadogBuildListener.onCompleted(run, mock(TaskListener.class));

        JSONObject series = capturePostMetricRequestPayload();
        assertEquals("jenkins.job.duration", series.getString("metric"));
        assertNotEquals(0, valueOfFirstPoint(series), 0);
    }



    private Run run() throws Exception {
        Run run = mock(Run.class);
        when(run.getResult()).thenReturn(Result.SUCCESS);
        when(run.getEnvironment(any(TaskListener.class))).thenReturn(envVars());

        Job job = job();
        when(run.getParent()).thenReturn(job);

        return run;
    }

    private Job job() {
        Job job = mock(Job.class);
        when(job.getName()).thenReturn("test-job");
        return job;
    }

    private EnvVars envVars() {
        return new EnvVars();
    }

    private DatadogBuildListener.DescriptorImpl descriptor() {
        return mock(DatadogBuildListener.DescriptorImpl.class);
    }

    private JSONObject capturePostMetricRequestPayload() throws IOException {
        PowerMockito.verifyStatic();
        ArgumentCaptor<JSONObject> captor = ArgumentCaptor.forClass(JSONObject.class);
        DatadogHttpRequests.post(captor.capture(), eq(DatadogBuildListener.METRIC));

        return captor.getValue().getJSONArray("series").getJSONObject(0);
    }

    private double valueOfFirstPoint(JSONObject series) {
        return series.getJSONArray("points").getJSONArray(0).getDouble(1);
    }
}
@@ -86,98 +86,9 @@
 del.
-Job;%0Aimport hudson.model.Result;%0Aimport hudson.model.Run;%0Aimport hudson.model.TaskListener
+*
 ;%0Aim
@@ -2669,24 +2669,139 @@
 Job job() %7B%0A
+        ItemGroup parent = mock(ItemGroup.class);%0A        when(parent.getFullDisplayName()).thenReturn(%22parent%22);%0A%0A
         Job 
@@ -2875,16 +2875,67 @@
 -job%22);%0A
+        when(job.getParent()).thenReturn(parent);%0A%0A
         

Fix tests after merging master