/*
 * Copyright (c) 2017, 2018 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0, which is available at
 * http://www.eclipse.org/legal/epl-2.0.
 *
 * This Source Code may also be made available under the following Secondary
 * Licenses when the conditions for such availability set forth in the
 * Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
 * version 2 with the GNU Classpath Exception, which is available at
 * https://www.gnu.org/software/classpath/license.html.
 *
 * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
 */

package com.sun.ejb.devtest.client;

import java.io.*;
import java.util.*;
import javax.naming.*;
import jakarta.ejb.EJB;
import com.oracle.javaee7.samples.batch.cmt.chunk.*;
import com.sun.ejte.ccl.reporter.SimpleReporterAdapter;

public class Client {

    private static SimpleReporterAdapter stat =
        new SimpleReporterAdapter("appserv-tests");

    public static void main (String[] args) {

        stat.addDescription("batch-cmt-chunk");
        Client client = new Client(args);
        client.doTest();
        stat.printSummary("batch-cmt-chunk");
    }

    public Client (String[] args) {
    }

    private static @EJB JobSubmitter jobSubmitter;

    int MAX_JOB_SIZE = 2;
    long[] executionIds = new long[MAX_JOB_SIZE];

    public void doTest() {
        for (int i=0; i<MAX_JOB_SIZE; i++)
            executionIds[i] = -1;
        submitJobs();
        listBatchJobs();
        listBatchJobsInLongFormat();
        checkJobExecution(executionIds[0]);
            isJobExecutionOK(executionIds[0]);
            checkAllJobExecutions();
            checkIfOnlyJobsFromThisAppAreVisible();
    }

    public void submitJobs() {
        try {
            for (int i = 0; i< MAX_JOB_SIZE; i++) {
                executionIds[i] = jobSubmitter.submitJob("Simple-Validation-Job");
                checkBatchJobStatus(executionIds[i], 100);
            }
            boolean result = true;
            for (int i=0; i<MAX_JOB_SIZE; i++) {
               result = result && executionIds[i] != -1;
            }
            stat.addStatus("batch-cmt-chunk-test1", (result ? stat.PASS : stat.FAIL));
        } catch (Exception ex) {
            stat.addStatus("batch-cmt-chunk-test1", stat.FAIL);
        }
    }

    public void listBatchJobs() {
        try {
            boolean status = true;
            Collection<String> jobs = jobSubmitter.listJobs(false);
            for (String job : jobs) {
                System.out.println("** JOB ==> " + job);
            }
            stat.addStatus("batch-cmt-chunk-test2", (status ? stat.PASS : stat.FAIL));
        } catch (Exception ex) {
            stat.addStatus("batch-cmt-chunk-test2", stat.FAIL);
        }
    }

    public void listBatchJobsInLongFormat() {
        try {
            boolean status = true;
            Collection<String> jobs = jobSubmitter.listJobs(true);
            for (String job : jobs) {
                System.out.println("** JOB ==> " + job);
            }
            stat.addStatus("batch-cmt-chunk-test3", (status ? stat.PASS : stat.FAIL));
        } catch (Exception ex) {
            stat.addStatus("batch-cmt-chunk-test3", stat.FAIL);
        }
    }

    public void checkJobExecution(long executionId) {
        try {
            boolean status = true;
            Map<String, String> map = jobSubmitter.toMap(executionId);

            stat.addStatus("batch-cmt-status-checkExe-jobName", map.get("jobName") != null ? stat.PASS : stat.FAIL);
            stat.addStatus("batch-cmt-status-checkExe-appName", map.get("appName") != null ? stat.PASS : stat.FAIL);
            stat.addStatus("batch-cmt-status-checkExe-instanceCount", map.get("instanceCount") != null ? stat.PASS : stat.FAIL);
            stat.addStatus("batch-cmt-status-checkExe-instanceID", map.get("instanceID") != null ? stat.PASS : stat.FAIL);
            stat.addStatus("batch-cmt-status-checkExe-executionID", map.get("executionID") != null ? stat.PASS : stat.FAIL);
            stat.addStatus("batch-cmt-status-checkExe-startTime", map.get("startTime") != null ? stat.PASS : stat.FAIL);
            stat.addStatus("batch-cmt-status-checkExe-batchStatus", map.get("batchStatus") != null ? stat.PASS : stat.FAIL);
            stat.addStatus("batch-cmt-status-checkExe-endTime", map.get("endTime") != null ? stat.PASS : stat.FAIL);

        } catch (Exception ex) {
            stat.addStatus("batch-cmt-chunk-test3", stat.FAIL);
        }
    }

    public void isJobExecutionOK(long executionId) {
        stat.addStatus("batch-cmt-status-checkExe-isJobExecutionOK", checkOneJobExecution(executionId) ? stat.PASS : stat.FAIL);
    }

    private boolean checkOneJobExecution(long executionId) {
        try {
            Map<String, String> map = jobSubmitter.toMap(executionId);
            return map != null &&
                    map.get("jobName") != null &&
                    map.get("appName") != null &&
                    map.get("instanceCount") != null &&
                    map.get("instanceID") != null &&
                    map.get("executionID") != null &&
                    map.get("startTime") != null &&
                    map.get("batchStatus") != null &&
                    map.get("endTime") != null;

        } catch (Exception ex) {

        }
        return false;
    }

    public void checkAllJobExecutions() {
       boolean result = true;
       for (long exeId : jobSubmitter.getAllExecutionIds(null)) {
           if (!checkOneJobExecution(exeId)) {
              result = false;
              break;
           }
       }
        stat.addStatus("batch-cmt-status-checkExe-checkAllJobExecutions", result ? stat.PASS : stat.FAIL);
    }

    public void checkIfOnlyJobsFromThisAppAreVisible() {
        try {
            boolean status = true;
            for (long exeId : jobSubmitter.getAllExecutionIds(null)) {
                Map<String, String> map = jobSubmitter.toMap(exeId);
                String jobName = map.get("jobName");
                String appName = map.get("appName");
                if (!jobName.startsWith("Simple-Validation-Job") || !appName.startsWith("server-config:Simple-ValidationApp")) {
                    System.out.println("***********************************************");
                    System.out.println("*** Job From another app? " + jobName + "; " + appName + " ***");
                    System.out.println("***********************************************");
                    status = false;
                    break;
                }
            }
            stat.addStatus("batch-cmt-chunk-checkIfOnlyJobsFromThisAppAreVisible", (status ? stat.PASS : stat.FAIL));
        } catch (Exception ex) {
            stat.addStatus("batch-cmt-chunk-checkIfOnlyJobsFromThisAppAreVisible", stat.FAIL);
        }
    }

    public void checkBatchJobStatus(long executionId, int sec) {
        while (sec-- > 0) {
            try {
                String status = jobSubmitter.getJobExitStatus(executionId);
                if ("COMPLETED".equalsIgnoreCase(status) || "FAILED".equalsIgnoreCase(status)) {
                    System.out.println("** checkBatchJobStatus[" + executionId + "]  ==> " + status);
                    break;
                }
                System.out.println("Will sleep for " + sec + " more seconds...");
                Thread.currentThread().sleep(1000);
            } catch (Exception ex) {
            }
        }
    }

}

