/*
 * Copyright 2012 International Business Machines Corp.
 * 
 * See the NOTICE file distributed with this work for additional information
 * regarding copyright ownership. Licensed 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.batchee.container.impl.jobinstance;

import org.apache.batchee.container.impl.JobContextImpl;
import org.apache.batchee.container.impl.JobInstanceImpl;
import org.apache.batchee.container.jsl.JobModelResolver;
import org.apache.batchee.container.modelresolver.PropertyResolver;
import org.apache.batchee.container.modelresolver.PropertyResolverFactory;
import org.apache.batchee.container.navigator.ModelNavigator;
import org.apache.batchee.container.navigator.NavigatorFactory;
import org.apache.batchee.container.services.InternalJobExecution;
import org.apache.batchee.container.services.JobStatusManagerService;
import org.apache.batchee.container.services.ServicesManager;
import org.apache.batchee.container.status.JobStatus;
import org.apache.batchee.jaxb.JSLJob;
import org.apache.batchee.jaxb.JSLProperties;
import org.apache.batchee.spi.PersistenceManagerService;

import javax.batch.operations.JobExecutionAlreadyCompleteException;
import javax.batch.operations.JobExecutionNotMostRecentException;
import javax.batch.operations.JobRestartException;
import javax.batch.operations.JobStartException;
import javax.batch.operations.NoSuchJobExecutionException;
import javax.batch.runtime.BatchStatus;
import javax.batch.runtime.JobInstance;
import java.util.Properties;

public class JobExecutionHelper {

    private JobExecutionHelper() {
        // private utility class ct
    }

    private static ModelNavigator<JSLJob> getResolvedJobNavigator(final String jobXml, final Properties jobParameters, final boolean parallelExecution) {
        final JSLJob jobModel = new JobModelResolver().resolveModel(jobXml);
        final PropertyResolver<JSLJob> propResolver = PropertyResolverFactory.createJobPropertyResolver(parallelExecution);
        propResolver.substituteProperties(jobModel, jobParameters);
        return NavigatorFactory.createJobNavigator(jobModel);
    }

    private static ModelNavigator<JSLJob> getResolvedJobNavigator(final JSLJob jobModel, final Properties jobParameters, final boolean parallelExecution) {
        final PropertyResolver<JSLJob> propResolver = PropertyResolverFactory.createJobPropertyResolver(parallelExecution);
        propResolver.substituteProperties(jobModel, jobParameters);
        return NavigatorFactory.createJobNavigator(jobModel);
    }

    private static JobContextImpl getJobContext(ModelNavigator<JSLJob> jobNavigator) {
        final JSLProperties jslProperties;
        if (jobNavigator.getRootModelElement() != null) {
            jslProperties = jobNavigator.getRootModelElement().getProperties();
        } else {
            jslProperties = new JSLProperties();
        }
        return new JobContextImpl(jobNavigator, jslProperties);
    }

    private static JobInstance getNewJobInstance(final ServicesManager servicesManager, final String name, final String jobXml) {
        return servicesManager.service(PersistenceManagerService.class).createJobInstance(
                name, jobXml);
    }

    private static JobInstance getNewSubJobInstance(final ServicesManager servicesManager, final String name) {
        return servicesManager.service(PersistenceManagerService.class).createSubJobInstance(name);
    }

    private static JobStatus createNewJobStatus(final JobStatusManagerService statusManagerService, final JobInstance jobInstance) {
        final long instanceId = jobInstance.getInstanceId();
        final JobStatus jobStatus = statusManagerService.createJobStatus(instanceId);
        jobStatus.setJobInstance(jobInstance);
        return jobStatus;
    }

    private static void validateRestartableFalseJobsDoNotRestart(final JSLJob jobModel)
        throws JobRestartException {
        if (jobModel.getRestartable() != null && jobModel.getRestartable().equalsIgnoreCase("false")) {
            throw new JobRestartException("Job Restartable attribute is false, Job cannot be restarted.");
        }
    }

    public static RuntimeJobExecution startJob(final ServicesManager servicesManager, final String jobXML, final Properties jobParameters) throws JobStartException {
        final JSLJob jobModel = new JobModelResolver().resolveModel(jobXML);
        final ModelNavigator<JSLJob> jobNavigator = getResolvedJobNavigator(jobModel, jobParameters, false);
        final JobContextImpl jobContext = getJobContext(jobNavigator);
        final JobInstance jobInstance = getNewJobInstance(servicesManager, jobNavigator.getRootModelElement().getId(), jobXML);
        final RuntimeJobExecution executionHelper =
                servicesManager.service(PersistenceManagerService.class).createJobExecution(jobInstance, jobParameters, jobContext.getBatchStatus());

        executionHelper.prepareForExecution(jobContext);

        final JobStatusManagerService statusManagerService = servicesManager.service(JobStatusManagerService.class);
        final JobStatus jobStatus = createNewJobStatus(statusManagerService, jobInstance);
        statusManagerService.updateJobStatus(jobStatus);

        return executionHelper;
    }

    public static RuntimeFlowInSplitExecution startFlowInSplit(final ServicesManager servicesManager, final JSLJob jobModel) throws JobStartException {
        final ModelNavigator<JSLJob> jobNavigator = getResolvedJobNavigator(jobModel, null, true);
        final JobContextImpl jobContext = getJobContext(jobNavigator);
        final JobInstance jobInstance = getNewSubJobInstance(servicesManager, jobNavigator.getRootModelElement().getId());
        final RuntimeFlowInSplitExecution executionHelper =
                servicesManager.service(PersistenceManagerService.class).createFlowInSplitExecution(jobInstance, jobContext.getBatchStatus());

        executionHelper.prepareForExecution(jobContext);

        final JobStatusManagerService statusManagerService = servicesManager.service(JobStatusManagerService.class);
        final JobStatus jobStatus = createNewJobStatus(statusManagerService, jobInstance);
        statusManagerService.updateJobStatus(jobStatus);

        return executionHelper;
    }

    public static RuntimeJobExecution startPartition(final ServicesManager servicesManager, final JSLJob jobModel, final Properties jobParameters) throws JobStartException {
        final ModelNavigator<JSLJob> jobNavigator = getResolvedJobNavigator(jobModel, jobParameters, true);
        final JobContextImpl jobContext = getJobContext(jobNavigator);

        final JobInstance jobInstance = getNewSubJobInstance(servicesManager, jobNavigator.getRootModelElement().getId());

        final RuntimeJobExecution executionHelper =
                servicesManager.service(PersistenceManagerService.class).createJobExecution(jobInstance, jobParameters, jobContext.getBatchStatus());

        executionHelper.prepareForExecution(jobContext);

        final JobStatusManagerService statusManagerService = servicesManager.service(JobStatusManagerService.class);
        final JobStatus jobStatus = createNewJobStatus(statusManagerService, jobInstance);
        statusManagerService.updateJobStatus(jobStatus);

        return executionHelper;
    }

    private static void validateJobInstanceNotCompleteOrAbandonded(final JobStatus jobStatus) throws JobRestartException, JobExecutionAlreadyCompleteException {
        if (jobStatus.getBatchStatus() == null) {
            throw new IllegalStateException("On restart, we didn't find an earlier batch status.");
        }

        if (jobStatus.getBatchStatus().equals(BatchStatus.COMPLETED)) {
            throw new JobExecutionAlreadyCompleteException("Already completed job instance = " + jobStatus.getJobInstanceId());
        } else if (jobStatus.getBatchStatus().equals(BatchStatus.ABANDONED)) {
            throw new JobRestartException("Abandoned job instance = " + jobStatus.getJobInstanceId());
        }
    }

    private static void validateJobExecutionIsMostRecent(final PersistenceManagerService persistenceManagerService, final long jobInstanceId, final long executionId)
            throws JobExecutionNotMostRecentException {
        final long mostRecentExecutionId = persistenceManagerService.getMostRecentExecutionId(jobInstanceId);
        if (mostRecentExecutionId != executionId) {
            throw new JobExecutionNotMostRecentException("ExecutionId: " + executionId + " is not the most recent execution.");
        }
    }

    public static RuntimeJobExecution restartPartition(final ServicesManager servicesManager, final long execId, final JSLJob gennedJobModel, final Properties partitionProps)
            throws JobRestartException,
        JobExecutionAlreadyCompleteException, JobExecutionNotMostRecentException, NoSuchJobExecutionException {
        return restartExecution(servicesManager, execId, gennedJobModel, partitionProps, true, false);
    }

    public static RuntimeFlowInSplitExecution restartFlowInSplit(final ServicesManager servicesManager, final long execId, final JSLJob gennedJobModel)
            throws JobRestartException, JobExecutionAlreadyCompleteException, JobExecutionNotMostRecentException, NoSuchJobExecutionException {
        return (RuntimeFlowInSplitExecution) restartExecution(servicesManager, execId, gennedJobModel, null, true, true);
    }

    public static RuntimeJobExecution restartJob(final ServicesManager servicesManager, final long executionId, final Properties restartJobParameters)
            throws JobRestartException, JobExecutionAlreadyCompleteException, JobExecutionNotMostRecentException, NoSuchJobExecutionException {
        return restartExecution(servicesManager, executionId, null, restartJobParameters, false, false);
    }

    private static RuntimeJobExecution restartExecution(final ServicesManager servicesManager, final long executionId, final JSLJob gennedJobModel,
                                                        final Properties restartJobParameters, final boolean parallelExecution, final boolean flowInSplit)
            throws JobRestartException, JobExecutionAlreadyCompleteException, JobExecutionNotMostRecentException, NoSuchJobExecutionException {

        final PersistenceManagerService persistenceManagerService = servicesManager.service(PersistenceManagerService.class);
        final JobStatusManagerService jobStatusManagerService = servicesManager.service(JobStatusManagerService.class);

        final long jobInstanceId = persistenceManagerService.getJobInstanceIdByExecutionId(executionId);
        final JobStatus jobStatus = jobStatusManagerService.getJobStatus(jobInstanceId);

        validateJobExecutionIsMostRecent(persistenceManagerService, jobInstanceId, executionId);

        validateJobInstanceNotCompleteOrAbandonded(jobStatus);

        final JobInstanceImpl jobInstance = jobStatus.getJobInstance();

        final ModelNavigator<JSLJob> jobNavigator;
        // If we are in a parallel job that is genned use the regenned JSL.
        if (gennedJobModel == null) {
            jobNavigator = getResolvedJobNavigator(jobInstance.getJobXML(), restartJobParameters, parallelExecution);
        } else {
            jobNavigator = getResolvedJobNavigator(gennedJobModel, restartJobParameters, parallelExecution);
        }
        // JSLJob jobModel = ModelResolverFactory.createJobResolver().resolveModel(jobInstance.getJobXML());
        validateRestartableFalseJobsDoNotRestart(jobNavigator.getRootModelElement());

        final JobContextImpl jobContext = getJobContext(jobNavigator);

        final RuntimeJobExecution executionHelper;
        if (flowInSplit) {
            executionHelper = persistenceManagerService.createFlowInSplitExecution(jobInstance, jobContext.getBatchStatus());
        } else {
            executionHelper = persistenceManagerService.createJobExecution(jobInstance, restartJobParameters, jobContext.getBatchStatus());
        }
        executionHelper.prepareForExecution(jobContext, jobStatus.getRestartOn());
        jobStatusManagerService.updateJobStatusWithNewExecution(jobInstance.getInstanceId(), executionHelper.getExecutionId());

        return executionHelper;
    }

    public static InternalJobExecution getPersistedJobOperatorJobExecution(final PersistenceManagerService persistenceManagerService, final long jobExecutionId)
            throws NoSuchJobExecutionException {
        return persistenceManagerService.jobOperatorGetJobExecution(jobExecutionId);
    }


    public static JobInstance getJobInstance(final JobStatusManagerService statusManagerService, final long executionId) {
        return statusManagerService.getJobStatusFromExecutionId(executionId).getJobInstance();
    }
}
