/**
 * 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.fineract.integrationtests.common;

import static java.time.Instant.now;
import static org.awaitility.Awaitility.await;
import static org.hamcrest.core.Is.is;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;

import com.google.gson.Gson;
import io.restassured.builder.ResponseSpecBuilder;
import io.restassured.specification.RequestSpecification;
import io.restassured.specification.ResponseSpecification;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.temporal.ChronoUnit;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.apache.fineract.client.models.PutJobsJobIDRequest;
import org.apache.fineract.infrastructure.businessdate.domain.BusinessDateType;
import org.apache.fineract.infrastructure.core.service.DateUtils;
import org.apache.fineract.integrationtests.client.IntegrationTest;
import org.hamcrest.MatcherAssert;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SchedulerJobHelper extends IntegrationTest {

    private static final Logger LOG = LoggerFactory.getLogger(SchedulerJobHelper.class);
    private final RequestSpecification requestSpec;
    private final ResponseSpecification response200Spec;
    private final ResponseSpecification response202Spec;

    public SchedulerJobHelper(final RequestSpecification requestSpec) {
        this.requestSpec = requestSpec;
        this.response200Spec = new ResponseSpecBuilder().expectStatusCode(200).build();
        this.response202Spec = new ResponseSpecBuilder().expectStatusCode(202).build();
    }

    private List<Map<String, Object>> getAllSchedulerJobs() {
        final String GET_ALL_SCHEDULER_JOBS_URL = "/fineract-provider/api/v1/jobs?" + Utils.TENANT_IDENTIFIER;
        LOG.info("------------------------ RETRIEVING ALL SCHEDULER JOBS -------------------------");
        List<Map<String, Object>> response = Utils.performServerGet(requestSpec, response200Spec, GET_ALL_SCHEDULER_JOBS_URL, "");
        assertNotNull(response);
        return response;
    }

    private <T> List<T> getAllSchedulerJobDetails(Function<Map<String, Object>, T> mapper) {
        return getAllSchedulerJobs().stream().map(mapper).collect(Collectors.toList());
    }

    public List<Integer> getAllSchedulerJobIds() {
        return getAllSchedulerJobDetails(map -> (Integer) map.get("jobId"));
    }

    public List<String> getAllSchedulerJobNames() {
        return getAllSchedulerJobDetails(map -> (String) map.get("displayName"));
    }

    public Map<String, Object> getSchedulerJobById(int jobId) {
        final String GET_SCHEDULER_JOB_BY_ID_URL = "/fineract-provider/api/v1/jobs/" + jobId + "?" + Utils.TENANT_IDENTIFIER;
        LOG.info("------------------------ RETRIEVING SCHEDULER JOB BY ID -------------------------");
        final Map<String, Object> response = Utils.performServerGet(requestSpec, response200Spec, GET_SCHEDULER_JOB_BY_ID_URL, "");
        LOG.info("{}", response.toString());
        assertNotNull(response);
        return response;
    }

    public Boolean getSchedulerStatus() {
        final String GET_SCHEDULER_STATUS_URL = "/fineract-provider/api/v1/scheduler?" + Utils.TENANT_IDENTIFIER;
        LOG.info("------------------------ RETRIEVING SCHEDULER STATUS -------------------------");
        final Map<String, Object> response = Utils.performServerGet(requestSpec, response200Spec, GET_SCHEDULER_STATUS_URL, "");
        return (Boolean) response.get("active");
    }

    public void updateSchedulerStatus(final boolean on) {
        String command = on ? "start" : "stop";
        ok(fineract().jobsScheduler.changeSchedulerStatus(command));
    }

    public Map<String, Object> updateSchedulerJob(int jobId, final boolean active) {
        final String UPDATE_SCHEDULER_JOB_URL = "/fineract-provider/api/v1/jobs/" + jobId + "?" + Utils.TENANT_IDENTIFIER;
        LOG.info("------------------------ UPDATING SCHEDULER JOB -------------------------");
        final Map<String, Object> response = Utils.performServerPut(requestSpec, response200Spec, UPDATE_SCHEDULER_JOB_URL,
                updateSchedulerJobAsJSON(active), "changes");
        return response;
    }

    public void updateSchedulerJob(long jobId, PutJobsJobIDRequest request) {
        ok(fineract().jobs.updateJobDetail(jobId, request));
    }

    private static String updateSchedulerJobAsJSON(final boolean active) {
        final Map<String, String> map = new HashMap<>();
        map.put("active", Boolean.toString(active));
        LOG.info("map :  {}", map);
        return new Gson().toJson(map);
    }

    public void runSchedulerJob(int jobId) {
        final ResponseSpecification responseSpec = new ResponseSpecBuilder().expectStatusCode(202).build();
        runSchedulerJob(jobId, responseSpec);
    }

    public void runSchedulerJob(int jobId, ResponseSpecification responseSpec) {
        final String RUN_SCHEDULER_JOB_URL = "/fineract-provider/api/v1/jobs/" + jobId + "?command=executeJob&" + Utils.TENANT_IDENTIFIER;
        LOG.info("------------------------ RUN SCHEDULER JOB -------------------------");
        Utils.performServerPost(requestSpec, responseSpec, RUN_SCHEDULER_JOB_URL, runSchedulerJobAsJSON(), null);
    }

    private static String runSchedulerJobAsJSON() {
        final Map<String, String> map = new HashMap<>();
        String runSchedulerJob = new Gson().toJson(map);
        LOG.info(runSchedulerJob);
        return runSchedulerJob;
    }

    public int getSchedulerJobIdByName(String jobName) {
        List<Map<String, Object>> allSchedulerJobsData = getAllSchedulerJobs();
        for (Integer jobIndex = 0; jobIndex < allSchedulerJobsData.size(); jobIndex++) {
            if (allSchedulerJobsData.get(jobIndex).get("displayName").equals(jobName)) {
                return (Integer) allSchedulerJobsData.get(jobIndex).get("jobId");
            }
        }
        throw new IllegalArgumentException(
                "No such named Job (see org.apache.fineract.infrastructure.jobs.service.JobName enum):" + jobName);
    }

    /**
     * Launches a Job and awaits its completion.
     *
     * @param jobName
     *            displayName (see {@link org.apache.fineract.infrastructure.jobs.service.JobName}) of Scheduler Job
     *
     * @author Michael Vorburger.ch
     */
    public void executeAndAwaitJob(String jobName) {
        final Duration timeout = Duration.ofMinutes(4);
        final Duration pause = Duration.ofSeconds(2);
        DateTimeFormatter df = DateTimeFormatter.ISO_INSTANT; // FINERACT-926
        Instant beforeExecuteTime = now().truncatedTo(ChronoUnit.SECONDS);

        // Stop the Scheduler while we manually trigger execution of job, to
        // avoid side effects and simplify debugging when readings logs
        updateSchedulerStatus(false);

        // Executing Scheduler Job
        int jobId = getSchedulerJobIdByName(jobName);
        runSchedulerJob(jobId);

        // Await JobDetailData.lastRunHistory [JobDetailHistoryData]
        // jobRunStartTime >= beforeExecuteTime (or timeout)
        // jobRunEndTime to be both set and >= jobRunStartTime (or timeout)
        Map<String, String> finalLastRunHistory = await().atMost(timeout).pollInterval(pause).until(jobLastRunHistorySupplier(jobId),
                lastRunHistory -> {
                    String jobRunStartText = lastRunHistory.get("jobRunStartTime");
                    if (jobRunStartText == null) {
                        return false;
                    }
                    String jobRunEndText = lastRunHistory.get("jobRunEndTime");
                    if (jobRunEndText == null) {
                        return false;
                    }
                    Instant jobRunStartTime = df.parse(jobRunStartText, Instant::from);
                    Instant jobRunEndTime = df.parse(jobRunEndText, Instant::from);
                    return !jobRunStartTime.isBefore(beforeExecuteTime) && !jobRunEndTime.isBefore(jobRunStartTime);
                });

        // Verify triggerType
        MatcherAssert.assertThat(finalLastRunHistory.get("triggerType"), is("application"));

        // Verify status & propagate jobRunErrorMessage and/or jobRunErrorLog
        // (if any)
        String status = finalLastRunHistory.get("status");
        if (!status.equals("success")) {
            fail("Job status is not success: " + finalLastRunHistory.toString());
        }

        // PS: Checking getSchedulerJobHistory() [/runhistory] is pointless,
        // because the lastRunHistory JobDetailHistoryData is already part of
        // JobDetailData anyway.
    }

    public void fastForwardTime(LocalDate lastBusinessDateBeforeFastForward, LocalDate dateToFastForward, String jobName,
            ResponseSpecification responseSpec) {
        while (DateUtils.isBefore(lastBusinessDateBeforeFastForward, dateToFastForward)) {
            BusinessDateHelper.updateBusinessDate(requestSpec, responseSpec, BusinessDateType.COB_DATE, lastBusinessDateBeforeFastForward);
            executeAndAwaitJob(jobName);
            lastBusinessDateBeforeFastForward = lastBusinessDateBeforeFastForward.plusDays(1);
        }
    }

    @SuppressWarnings("unchecked")
    private Callable<Map<String, String>> jobLastRunHistorySupplier(int jobId) {
        return () -> {
            Map<String, Object> job = getSchedulerJobById(jobId);
            if (job == null) {
                return null;
            }
            return (Map<String, String>) job.get("lastRunHistory");
        };
    }
}
