/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements.  See the NOTICE file
distributed with this work for additional information
regarding copyright ownership.  The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License.  You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied.  See the License for the
specific language governing permissions and limitations
under the License.
*/

package org.apache.griffin.core.job;

import static org.apache.griffin.core.exception.GriffinExceptionMessage.JOB_ID_DOES_NOT_EXIST;
import static org.apache.griffin.core.exception.GriffinExceptionMessage.JOB_NAME_DOES_NOT_EXIST;
import static org.apache.griffin.core.util.EntityMocksHelper.createGriffinJob;
import static org.hamcrest.CoreMatchers.is;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doThrow;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.util.Arrays;
import java.util.Collections;

import org.apache.griffin.core.exception.GriffinException;
import org.apache.griffin.core.exception.GriffinExceptionHandler;
import org.apache.griffin.core.job.entity.AbstractJob;
import org.apache.griffin.core.job.entity.JobHealth;
import org.apache.griffin.core.job.entity.JobInstanceBean;
import org.apache.griffin.core.job.entity.LivySessionStates;
import org.apache.griffin.core.util.URLHelper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

@RunWith(SpringRunner.class)
public class JobControllerTest {

    private MockMvc mvc;

    @Mock
    private JobServiceImpl service;

    @InjectMocks
    private JobController controller;

    @Before
    public void setup() {
        mvc = MockMvcBuilders
                .standaloneSetup(controller)
                .setControllerAdvice(new GriffinExceptionHandler())
                .build();
    }


    @Test
    public void testGetJobs() throws Exception {
        AbstractJob jobBean = createGriffinJob();
        jobBean.setJobName("job_name");
        given(service.getAliveJobs(""))
                .willReturn(Collections.singletonList(jobBean));

        mvc.perform(
                get(URLHelper.API_VERSION_PATH + "/jobs")
                        .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$[0]['job.name']", is("job_name")));
    }

    @Test
    public void testDeleteJobByIdForSuccess() throws Exception {
        doNothing().when(service).deleteJob(1L);

        mvc.perform(delete(URLHelper.API_VERSION_PATH + "/jobs/1"))
                .andExpect(status().isNoContent());
    }

    @Test
    public void testDeleteJobByIdForFailureWithNotFound() throws Exception {
        doThrow(new GriffinException.NotFoundException(JOB_ID_DOES_NOT_EXIST))
                .when(service).deleteJob(1L);

        mvc.perform(delete(URLHelper.API_VERSION_PATH + "/jobs/1"))
                .andExpect(status().isNotFound());
    }

    @Test
    public void testDeleteJobByIdForFailureWithException() throws Exception {
        doThrow(new GriffinException.ServiceException("Failed to delete job",
                new Exception()))
                .when(service).deleteJob(1L);

        mvc.perform(delete(URLHelper.API_VERSION_PATH + "/jobs/1"))
                .andExpect(status().isInternalServerError());
    }

    @Test
    public void testDeleteJobByNameForSuccess() throws Exception {
        String jobName = "jobName";
        doNothing().when(service).deleteJob(jobName);

        mvc.perform(delete(URLHelper.API_VERSION_PATH + "/jobs").param("jobName"
                , jobName))
                .andExpect(status().isNoContent());
    }

    @Test
    public void testDeleteJobByNameForFailureWithNotFound() throws Exception {
        String jobName = "jobName";
        doThrow(new GriffinException.NotFoundException(JOB_NAME_DOES_NOT_EXIST))
                .when(service).deleteJob(jobName);

        mvc.perform(delete(URLHelper.API_VERSION_PATH + "/jobs").param("jobName"
                , jobName))
                .andExpect(status().isNotFound());
    }

    @Test
    public void testDeleteJobByNameForFailureWithException() throws Exception {
        String jobName = "jobName";
        doThrow(new GriffinException.ServiceException("Failed to delete job",
                new Exception()))
                .when(service).deleteJob(jobName);

        mvc.perform(delete(URLHelper.API_VERSION_PATH + "/jobs").param("jobName"
                , jobName))
                .andExpect(status().isInternalServerError());
    }

    @Test
    public void testFindInstancesOfJob() throws Exception {
        int page = 0;
        int size = 2;
        JobInstanceBean jobInstance = new JobInstanceBean(1L, LivySessionStates
                .State.RUNNING, "", "", null, null);
        given(service.findInstancesOfJob(1L, page, size)).willReturn(Arrays
                .asList(jobInstance));

        mvc.perform(get(URLHelper.API_VERSION_PATH + "/jobs/instances").param
                ("jobId", String.valueOf(1L))
                .param("page", String.valueOf(page)).param("size",
                        String.valueOf(size)))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.[0].state", is("RUNNING")));
    }

    @Test
    public void testGetHealthInfo() throws Exception {
        JobHealth jobHealth = new JobHealth(1, 3);
        given(service.getHealthInfo()).willReturn(jobHealth);

        mvc.perform(get(URLHelper.API_VERSION_PATH + "/jobs/health"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.healthyJobCount", is(1)));
    }
}
