/*
 * 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.batchee.container.services.persistence;

import org.apache.batchee.container.impl.JobExecutionImpl;
import org.apache.batchee.container.impl.JobInstanceImpl;
import org.apache.batchee.container.impl.MetricImpl;
import org.apache.batchee.container.impl.StepContextImpl;
import org.apache.batchee.container.impl.StepExecutionImpl;
import org.apache.batchee.container.impl.controller.PartitionedStepBuilder;
import org.apache.batchee.container.impl.controller.chunk.CheckpointData;
import org.apache.batchee.container.impl.controller.chunk.CheckpointDataKey;
import org.apache.batchee.container.impl.jobinstance.RuntimeFlowInSplitExecution;
import org.apache.batchee.container.impl.jobinstance.RuntimeJobExecution;
import org.apache.batchee.container.services.InternalJobExecution;
import org.apache.batchee.container.status.JobStatus;
import org.apache.batchee.container.status.StepStatus;
import org.apache.batchee.spi.PersistenceManagerService;

import javax.batch.operations.NoSuchJobExecutionException;
import javax.batch.runtime.BatchStatus;
import javax.batch.runtime.JobInstance;
import javax.batch.runtime.Metric;
import javax.batch.runtime.StepExecution;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicLong;

public class MemoryPersistenceManagerService implements PersistenceManagerService {
    private static final Collection<BatchStatus> RUNNING_STATUSES = new CopyOnWriteArrayList<BatchStatus>() {{
        add(BatchStatus.STARTED);
        add(BatchStatus.STARTING);
        add(BatchStatus.STOPPING);
    }};

    protected static interface Structures extends Serializable {
        static class JobInstanceData implements Structures {
            protected JobInstanceImpl instance;
            protected String tag;
            protected JobStatus status;
            protected final List<ExecutionInstanceData> executions = new LinkedList<ExecutionInstanceData>();
            protected final Collection<CheckpointDataKey> checkpoints = new LinkedList<CheckpointDataKey>();
        }

        static class ExecutionInstanceData implements Structures {
            protected final List<StepExecution> stepExecutions = new LinkedList<StepExecution>();
            protected JobExecutionImpl execution;
        }

        static class StepExecutionInstanceData implements Structures {
            protected ExecutionInstanceData jobExec;
            protected StepExecutionImpl execution;
            protected StepStatus status;
        }
    }

    static class Data {
        protected final AtomicLong lastCleanedJobInstanceId = new AtomicLong(0);
        protected final AtomicLong jobInstanceIdGenerator = new AtomicLong();
        protected final AtomicLong executionInstanceIdGenerator = new AtomicLong();
        protected final AtomicLong stepExecutionIdGenerator = new AtomicLong();

        protected final Map<CheckpointDataKey, CheckpointData> checkpointData = new ConcurrentHashMap<CheckpointDataKey, CheckpointData>();
        protected final Map<Long, Structures.JobInstanceData> jobInstanceData = new ConcurrentHashMap<Long, Structures.JobInstanceData>();
        protected final Map<Long, Structures.ExecutionInstanceData> executionInstanceData = new ConcurrentHashMap<Long, Structures.ExecutionInstanceData>();
        protected final Map<Long, Structures.StepExecutionInstanceData> stepExecutionInstanceData = new ConcurrentHashMap<Long, Structures.StepExecutionInstanceData>();
    }

    private static final Data GLOBAL_DATA = new Data();

    private Data data;
    private int maxSize;

    // an extension point to be able to use whatever map you want, a distributed/filtered/size-limited one for instance
    protected Data newData() {
        return new Data();
    }

    @Override
    public void init(final Properties batchConfig) {
        if ("true".equalsIgnoreCase(batchConfig.getProperty("persistence.memory.global", "false"))) {
            data = GLOBAL_DATA;
        } else {
            data = newData();
        }
        maxSize = Integer.parseInt(batchConfig.getProperty("persistence.memory.max-jobs-instances", "1000"));
    }

    @Override
    public int jobOperatorGetJobInstanceCount(final String jobName) {
        return jobOperatorGetJobInstanceCount(jobName, null);
    }

    @Override
    public int jobOperatorGetJobInstanceCount(final String jobName, final String appTag) {
        final boolean hasTag = appTag != null;
        int i = 0;
        for (final Structures.JobInstanceData jobInstanceData : data.jobInstanceData.values()) {
            if (jobInstanceData.instance.getJobName().equals(jobName) && (!hasTag || appTag.equals(jobInstanceData.tag))) {
                i++;
            }
        }
        return i;
    }

    @Override
    public Map<Long, String> jobOperatorGetExternalJobInstanceData() {
        final Map<Long, String> out = new HashMap<Long, String>();
        for (final Structures.JobInstanceData jobInstanceData : data.jobInstanceData.values()) {
            if (jobInstanceData.instance.getJobName() != null && !jobInstanceData.instance.getJobName().startsWith(PartitionedStepBuilder.JOB_ID_SEPARATOR)) {
                out.put(jobInstanceData.instance.getInstanceId(), jobInstanceData.instance.getJobName());
            }
        }
        return out;
    }

    @Override
    public Set<String> getJobNames() {
        Set<String> jobNames = new HashSet<String>();
        for (final Structures.JobInstanceData jobInstanceData : data.jobInstanceData.values()) {
            if (jobInstanceData.instance.getJobName() != null && !jobInstanceData.instance.getJobName().startsWith(PartitionedStepBuilder.JOB_ID_SEPARATOR)) {
                jobNames.add(jobInstanceData.instance.getJobName());
            }
        }
        return jobNames;
    }

    @Override
    public List<Long> jobOperatorGetJobInstanceIds(final String jobName, final int start, final int count) {
        return jobOperatorGetJobInstanceIds(jobName, null, start, count);
    }

    @Override
    public List<Long> jobOperatorGetJobInstanceIds(final String jobName, final String appTag, final int start, final int count) {
        final List<Long> out = new LinkedList<Long>();
        for (final Structures.JobInstanceData jobInstanceData : data.jobInstanceData.values()) {
            if (jobInstanceData.instance.getJobName() != null && jobInstanceData.instance.getJobName().equals(jobName)) {
                final boolean hasTag = appTag != null;
                if (!hasTag || appTag.equals(jobInstanceData.tag)) {
                    out.add(jobInstanceData.instance.getInstanceId());
                }
            }
        }

        // sorting could be optimized a bit but is it necessary for this impl?
        Collections.sort(out);
        // Collections.reverse(out);

        if (out.size() > 0) {
            try {
                return out.subList(start, start + count);
            } catch (final IndexOutOfBoundsException oobEx) {
                return out.subList(start, out.size());
            }
        }

        return out;
    }

    @Override
    public Timestamp jobOperatorQueryJobExecutionTimestamp(final long key, final TimestampType timestampType) {
        return null; // avoid infinite loops
    }

    @Override
    public String jobOperatorQueryJobExecutionBatchStatus(final long key) {
        return null; // avoid infinite loops
    }

    @Override
    public String jobOperatorQueryJobExecutionExitStatus(final long key) {
        return null; // avoid infinite loops
    }

    @Override
    public List<StepExecution> getStepExecutionsForJobExecution(final long execid) {
        final Structures.ExecutionInstanceData executionInstanceData = data.executionInstanceData.get(execid);
        if (executionInstanceData == null) {
            return Collections.emptyList();
        }

        synchronized (executionInstanceData.stepExecutions) {
            return executionInstanceData.stepExecutions;
        }
    }

    @Override
    public void updateBatchStatusOnly(final long executionId, final BatchStatus batchStatus, final Timestamp timestamp) {
        final Structures.ExecutionInstanceData toUpdate = data.executionInstanceData.get(executionId);
        toUpdate.execution.setBatchStatus(batchStatus.name());
        toUpdate.execution.setLastUpdateTime(timestamp);
    }

    @Override
    public void markJobStarted(final long key, final Timestamp startTS) {
        final Structures.ExecutionInstanceData toUpdate = data.executionInstanceData.get(key);
        toUpdate.execution.setBatchStatus(BatchStatus.STARTED.name());
        toUpdate.execution.setLastUpdateTime(startTS);
        toUpdate.execution.setStartTime(startTS);
    }

    @Override
    public void updateWithFinalExecutionStatusesAndTimestamps(final long key, final BatchStatus batchStatus, final String exitStatus, final Timestamp updatets) {
        final Structures.ExecutionInstanceData toUpdate = data.executionInstanceData.get(key);
        if (batchStatus != null) {
            toUpdate.execution.setBatchStatus(batchStatus.name());
        } else {
            toUpdate.execution.setBatchStatus(null);
        }
        toUpdate.execution.setExitStatus(exitStatus);
        toUpdate.execution.setLastUpdateTime(updatets);
        toUpdate.execution.setEndTime(updatets);
    }

    @Override
    public InternalJobExecution jobOperatorGetJobExecution(final long jobExecutionId) {
        final Structures.ExecutionInstanceData executionInstanceData = data.executionInstanceData.get(jobExecutionId);
        if (executionInstanceData == null) {
            return null;
        }
        return executionInstanceData.execution;
    }

    @Override
    public Properties getParameters(final long executionId) throws NoSuchJobExecutionException {
        return data.executionInstanceData.get(executionId).execution.getJobParameters();
    }

    @Override
    public List<InternalJobExecution> jobOperatorGetJobExecutions(final long jobInstanceId) {
        final List<InternalJobExecution> list = new LinkedList<InternalJobExecution>();
        final Structures.JobInstanceData jobInstanceData = data.jobInstanceData.get(jobInstanceId);
        if (jobInstanceData == null || jobInstanceData.executions == null) {
            return list;
        }
        synchronized (jobInstanceData.executions) {
            for (final Structures.ExecutionInstanceData executionInstanceData : jobInstanceData.executions) {
                list.add(executionInstanceData.execution);
            }
        }
        return list;
    }

    @Override
    public Set<Long> jobOperatorGetRunningExecutions(final String jobName) {
        Structures.JobInstanceData jobInstanceData = null;
        for (final Structures.JobInstanceData instanceData : data.jobInstanceData.values()) {
            if (instanceData.instance.getJobName().equals(jobName)) {
                jobInstanceData = instanceData;
                break;
            }
        }

        if (jobInstanceData == null) {
            return Collections.emptySet();
        }

        final Set<Long> set = new HashSet<Long>();

        synchronized (jobInstanceData.executions) {
            for (final Structures.ExecutionInstanceData executionInstanceData : jobInstanceData.executions) {
                if (RUNNING_STATUSES.contains(executionInstanceData.execution.getBatchStatus())) {
                    set.add(executionInstanceData.execution.getExecutionId());
                }
            }
        }
        return set;
    }

    @Override
    public JobStatus getJobStatusFromExecution(final long executionId) {
        final Structures.ExecutionInstanceData executionInstanceData = data.executionInstanceData.get(executionId);
        if (executionInstanceData == null) {
            return null;
        }

        final Structures.JobInstanceData jobInstanceData = data.jobInstanceData.get(executionInstanceData.execution.getInstanceId());
        if (jobInstanceData == null) {
            return null;
        }
        return jobInstanceData.status;
    }

    @Override
    public long getJobInstanceIdByExecutionId(final long executionId) throws NoSuchJobExecutionException {
        final Structures.ExecutionInstanceData executionInstanceData = data.executionInstanceData.get(executionId);
        if (executionInstanceData == null) {
            throw new NoSuchJobExecutionException("Execution #" + executionId);
        }
        return executionInstanceData.execution.getInstanceId();
    }

    @Override
    public JobInstance createJobInstance(final String name, final String apptag, final String jobXml) {
        final JobInstanceImpl jobInstance = new JobInstanceImpl(data.jobInstanceIdGenerator.getAndIncrement(), jobXml);
        jobInstance.setJobName(name);

        final Structures.JobInstanceData jobInstanceData = new Structures.JobInstanceData();
        jobInstanceData.tag = apptag;
        jobInstanceData.instance = jobInstance;
        if (maxSize > 0 && data.jobInstanceData.size() >= maxSize) {
            synchronized (this) {
                while (data.jobInstanceData.size() >= maxSize) {
                    cleanUp(data.lastCleanedJobInstanceId.getAndIncrement());
                }
            }
        }
        data.jobInstanceData.put(jobInstance.getInstanceId(), jobInstanceData);

        return jobInstance;
    }

    @Override
    public RuntimeJobExecution createJobExecution(final JobInstance jobInstance, final Properties jobParameters, final BatchStatus batchStatus) {
        final Timestamp now = new Timestamp(System.currentTimeMillis());

        final Structures.ExecutionInstanceData executionInstanceData = createRuntimeJobExecutionEntry(jobInstance, jobParameters, batchStatus, now);
        executionInstanceData.execution.setJobName(jobInstance.getJobName());

        final RuntimeJobExecution jobExecution = new RuntimeJobExecution(jobInstance, executionInstanceData.execution.getExecutionId(), this);
        jobExecution.setBatchStatus(batchStatus.name());
        jobExecution.setCreateTime(now);
        jobExecution.setLastUpdateTime(now);

        return jobExecution;
    }

    private Structures.ExecutionInstanceData createRuntimeJobExecutionEntry(final JobInstance jobInstance, final Properties jobParameters,
                                                                            final BatchStatus batchStatus, final Timestamp now) {
        final Structures.ExecutionInstanceData executionInstanceData = new Structures.ExecutionInstanceData();
        final long id = data.executionInstanceIdGenerator.getAndIncrement();
        executionInstanceData.execution = new JobExecutionImpl(id, jobInstance.getInstanceId(), this);
        executionInstanceData.execution.setExecutionId(id);
        executionInstanceData.execution.setInstanceId(jobInstance.getInstanceId());
        executionInstanceData.execution.setBatchStatus(batchStatus.name());
        executionInstanceData.execution.setCreateTime(now);
        executionInstanceData.execution.setLastUpdateTime(now);
        executionInstanceData.execution.setJobParameters(jobParameters);

        data.executionInstanceData.put(id, executionInstanceData);
        final Structures.JobInstanceData jobInstanceData = data.jobInstanceData.get(jobInstance.getInstanceId());
        synchronized (jobInstanceData.executions) {
            jobInstanceData.executions.add(executionInstanceData);
        }
        return executionInstanceData;
    }

    @Override
    public StepExecutionImpl createStepExecution(final long rootJobExecId, final StepContextImpl stepContext) {
        final String batchStatus = stepContext.getBatchStatus() == null ? BatchStatus.STARTING.name() : stepContext.getBatchStatus().name();
        final String exitStatus = stepContext.getExitStatus();
        final String stepName = stepContext.getStepName();

        long readCount = 0;
        long writeCount = 0;
        long commitCount = 0;
        long rollbackCount = 0;
        long readSkipCount = 0;
        long processSkipCount = 0;
        long filterCount = 0;
        long writeSkipCount = 0;
        Timestamp startTime = stepContext.getStartTimeTS();
        Timestamp endTime = stepContext.getEndTimeTS();

        final Metric[] metrics = stepContext.getMetrics();
        for (final Metric metric : metrics) {
            if (metric.getType().equals(MetricImpl.MetricType.READ_COUNT)) {
                readCount = metric.getValue();
            } else if (metric.getType().equals(MetricImpl.MetricType.WRITE_COUNT)) {
                writeCount = metric.getValue();
            } else if (metric.getType().equals(MetricImpl.MetricType.PROCESS_SKIP_COUNT)) {
                processSkipCount = metric.getValue();
            } else if (metric.getType().equals(MetricImpl.MetricType.COMMIT_COUNT)) {
                commitCount = metric.getValue();
            } else if (metric.getType().equals(MetricImpl.MetricType.ROLLBACK_COUNT)) {
                rollbackCount = metric.getValue();
            } else if (metric.getType().equals(MetricImpl.MetricType.READ_SKIP_COUNT)) {
                readSkipCount = metric.getValue();
            } else if (metric.getType().equals(MetricImpl.MetricType.FILTER_COUNT)) {
                filterCount = metric.getValue();
            } else if (metric.getType().equals(MetricImpl.MetricType.WRITE_SKIP_COUNT)) {
                writeSkipCount = metric.getValue();
            }
        }
        final Serializable persistentData = stepContext.getPersistentUserData();

        return createStepExecution(rootJobExecId, batchStatus, exitStatus, stepName, readCount,
            writeCount, commitCount, rollbackCount, readSkipCount, processSkipCount, filterCount, writeSkipCount, startTime,
            endTime, persistentData);
    }

//CHECKSTYLE:OFF
    private StepExecutionImpl createStepExecution(final long rootJobExecId, final String batchStatus, final String exitStatus, final String stepName,
                                                  final long readCount, final long writeCount, final long commitCount, final long rollbackCount,
                                                  final long readSkipCount, final long processSkipCount, final long filterCount, final long writeSkipCount,
                                                  final Timestamp startTime, final Timestamp endTime, final Serializable persistentData) {
//CHECKSTYLE:ON

        final StepExecutionImpl stepExecution = new StepExecutionImpl(rootJobExecId, data.stepExecutionIdGenerator.getAndIncrement());
        stepExecution.setStepName(stepName);
        final Structures.ExecutionInstanceData executionInstanceData = data.executionInstanceData.get(rootJobExecId);
        if (executionInstanceData == null) {
            return null;
        }
        synchronized (executionInstanceData.stepExecutions) {
            executionInstanceData.stepExecutions.add(stepExecution);
        }

        final Structures.StepExecutionInstanceData stepExecutionInstanceData = new Structures.StepExecutionInstanceData();
        stepExecutionInstanceData.execution = stepExecution;
        updateStepExecutionInstanceData(executionInstanceData, batchStatus, exitStatus, stepName,
            readCount, writeCount, commitCount, rollbackCount,
            readSkipCount, processSkipCount, filterCount, writeSkipCount,
            startTime, endTime, persistentData,
            stepExecutionInstanceData);
        data.stepExecutionInstanceData.put(stepExecution.getStepExecutionId(), stepExecutionInstanceData);

        return stepExecution;
    }

//CHECKSTYLE:OFF
    private void updateStepExecutionInstanceData(final Structures.ExecutionInstanceData exec,
                                                 final String batchStatus,final  String exitStatus, final String stepName,
                                                 final long readCount, final long writeCount, final long commitCount, final long rollbackCount,
                                                 final long readSkipCount, final long processSkipCount, final long filterCount, final long writeSkipCount,
                                                 final Timestamp startTime, final Timestamp endTime,
                                                 final Serializable persistentData,
                                                 final Structures.StepExecutionInstanceData stepExecutionInstanceData) {
//CHECKSTYLE:ON
        stepExecutionInstanceData.jobExec = exec;
        stepExecutionInstanceData.execution.setExitStatus(exitStatus);
        stepExecutionInstanceData.execution.setBatchStatus(BatchStatus.valueOf(batchStatus));
        stepExecutionInstanceData.execution.setRollbackCount(rollbackCount);
        stepExecutionInstanceData.execution.setStepName(stepName);
        stepExecutionInstanceData.execution.setReadCount(readCount);
        stepExecutionInstanceData.execution.setWriteCount(writeCount);
        stepExecutionInstanceData.execution.setCommitCount(commitCount);
        stepExecutionInstanceData.execution.setRollbackCount(rollbackCount);
        stepExecutionInstanceData.execution.setReadSkipCount(readSkipCount);
        stepExecutionInstanceData.execution.setProcessSkipCount(processSkipCount);
        stepExecutionInstanceData.execution.setWriteSkipCount(writeSkipCount);
        stepExecutionInstanceData.execution.setFilterCount(filterCount);
        stepExecutionInstanceData.execution.setWriteSkipCount(writeSkipCount);
        stepExecutionInstanceData.execution.setStartTime(startTime);
        stepExecutionInstanceData.execution.setEndTime(endTime);
        stepExecutionInstanceData.execution.setPersistentUserData(persistentData);
    }

    @Override
    public void updateStepExecution(final long jobExecId, final StepContextImpl stepContext) {
        final long stepExecutionId = stepContext.getStepInternalExecID();
        final String batchStatus = stepContext.getBatchStatus() == null ? BatchStatus.STARTING.name() : stepContext.getBatchStatus().name();
        final String exitStatus = stepContext.getExitStatus();
        final String stepName = stepContext.getStepName();

        long readCount = 0;
        long writeCount = 0;
        long commitCount = 0;
        long rollbackCount = 0;
        long readSkipCount = 0;
        long processSkipCount = 0;
        long filterCount = 0;
        long writeSkipCount = 0;
        Timestamp startTime = stepContext.getStartTimeTS();
        Timestamp endTime = stepContext.getEndTimeTS();

        final Metric[] metrics = stepContext.getMetrics();
        for (final Metric metric : metrics) {
            if (metric.getType().equals(MetricImpl.MetricType.READ_COUNT)) {
                readCount = metric.getValue();
            } else if (metric.getType().equals(MetricImpl.MetricType.WRITE_COUNT)) {
                writeCount = metric.getValue();
            } else if (metric.getType().equals(MetricImpl.MetricType.PROCESS_SKIP_COUNT)) {
                processSkipCount = metric.getValue();
            } else if (metric.getType().equals(MetricImpl.MetricType.COMMIT_COUNT)) {
                commitCount = metric.getValue();
            } else if (metric.getType().equals(MetricImpl.MetricType.ROLLBACK_COUNT)) {
                rollbackCount = metric.getValue();
            } else if (metric.getType().equals(MetricImpl.MetricType.READ_SKIP_COUNT)) {
                readSkipCount = metric.getValue();
            } else if (metric.getType().equals(MetricImpl.MetricType.FILTER_COUNT)) {
                filterCount = metric.getValue();
            } else if (metric.getType().equals(MetricImpl.MetricType.WRITE_SKIP_COUNT)) {
                writeSkipCount = metric.getValue();
            }
        }
        final Serializable persistentData = stepContext.getPersistentUserData();

        updateStepExecution(stepExecutionId, jobExecId, batchStatus, exitStatus, stepName, readCount,
            writeCount, commitCount, rollbackCount, readSkipCount, processSkipCount, filterCount,
            writeSkipCount, startTime, endTime, persistentData);
    }

//CHECKSTYLE:OFF
    private void updateStepExecution(final long stepExecutionId, final long jobExecId, final String batchStatus, final String exitStatus, final String stepName,
                                     final long readCount, final long writeCount, final long commitCount, final long rollbackCount,
                                     final long readSkipCount, final long processSkipCount, final long filterCount, final long writeSkipCount,
                                     final Timestamp startTime, final Timestamp endTime, final Serializable persistentData) {
//CHECKSTYLE:ON
        final Structures.ExecutionInstanceData executionInstanceData = data.executionInstanceData.get(jobExecId);
        if (executionInstanceData == null) {
            return;
        }

        synchronized (executionInstanceData.stepExecutions) {
            for (final StepExecution execution : executionInstanceData.stepExecutions) {
                if (execution.getStepExecutionId() == stepExecutionId) {
                    updateStepExecutionInstanceData(executionInstanceData, batchStatus, exitStatus, stepName,
                        readCount, writeCount, commitCount, rollbackCount,
                        readSkipCount, processSkipCount, filterCount, writeSkipCount,
                        startTime, endTime, persistentData,
                        data.stepExecutionInstanceData.get(stepExecutionId));
                    break;
                }
            }
        }
    }

    @Override
    public JobStatus createJobStatus(final long jobInstanceId) {
        final Structures.JobInstanceData jobInstanceData = data.jobInstanceData.get(jobInstanceId);
        jobInstanceData.status = new JobStatus(jobInstanceId);
        return jobInstanceData.status;
    }

    @Override
    public JobStatus getJobStatus(final long instanceId) {
        final Structures.JobInstanceData jobInstanceData = data.jobInstanceData.get(instanceId);
        if (jobInstanceData == null) {
            return null;
        }
        return jobInstanceData.status;
    }

    @Override
    public void updateJobStatus(final long instanceId, final JobStatus jobStatus) {
        final Structures.JobInstanceData jobInstanceData = data.jobInstanceData.get(instanceId);
        if (jobInstanceData != null) {
            jobInstanceData.status = jobStatus;
        }
    }

    @Override
    public StepStatus createStepStatus(final long stepExecId) {
        final StepStatus stepStatus = new StepStatus(stepExecId);
        data.stepExecutionInstanceData.get(stepExecId).status = stepStatus;
        return stepStatus;
    }

    @Override
    public StepStatus getStepStatus(final long instanceId, final String stepName) {
        final Map<Date, StepStatus> statusMap = new TreeMap<Date, StepStatus>(ReverseDateComparator.INSTANCE);
        for (final Structures.StepExecutionInstanceData stepExecutionInstanceData : data.stepExecutionInstanceData.values()) {
            if (stepExecutionInstanceData.jobExec.execution.getInstanceId() == instanceId
                    && stepExecutionInstanceData.execution.getStepName().equals(stepName)
                    && stepExecutionInstanceData.status != null) {
                statusMap.put(stepExecutionInstanceData.jobExec.execution.getCreateTime(), stepExecutionInstanceData.status);
            }
        }
        if (statusMap.isEmpty()) {
            return null;
        }
        return statusMap.values().iterator().next();
    }

    @Override
    public void updateStepStatus(final long stepExecutionId, final StepStatus stepStatus) {
        final Structures.StepExecutionInstanceData stepExecutionInstanceData = data.stepExecutionInstanceData.get(stepExecutionId);
        if (stepExecutionInstanceData != null) {
            stepExecutionInstanceData.status = stepStatus;
        }
    }

    @Override
    public void setCheckpointData(final CheckpointDataKey key, final CheckpointData value) {
        data.checkpointData.put(key, value);
        final Structures.JobInstanceData jobInstanceData = data.jobInstanceData.get(key.getJobInstanceId());
        synchronized (jobInstanceData.checkpoints) {
            jobInstanceData.checkpoints.add(key);
        }
    }

    @Override
    public CheckpointData getCheckpointData(final CheckpointDataKey key) {
        return data.checkpointData.get(key);
    }

    @Override
    public long getMostRecentExecutionId(final long jobInstanceId) {
        final Map<Date, Structures.ExecutionInstanceData> filter = new TreeMap<Date, Structures.ExecutionInstanceData>(ReverseDateComparator.INSTANCE);
        final Structures.JobInstanceData jobInstanceData = data.jobInstanceData.get(jobInstanceId);
        synchronized (jobInstanceData.executions) {
            for (final Structures.ExecutionInstanceData exec : jobInstanceData.executions) {
                if (exec.execution.getInstanceId() == jobInstanceId) {
                    filter.put(exec.execution.getCreateTime(), exec);
                }
            }
        }
        if (filter.isEmpty()) {
            return -1;
        }
        return filter.values().iterator().next().execution.getExecutionId();
    }

    @Override
    public JobInstance createSubJobInstance(final String name, final String apptag) {
        return createJobInstance(name, apptag, null);
    }

    @Override
    public RuntimeFlowInSplitExecution createFlowInSplitExecution(final JobInstance jobInstance, final BatchStatus batchStatus) {
        final Timestamp now = new Timestamp(System.currentTimeMillis());
        final Structures.ExecutionInstanceData executionInstanceData = createRuntimeJobExecutionEntry(jobInstance, null, batchStatus, now);
        final RuntimeFlowInSplitExecution flowExecution = new RuntimeFlowInSplitExecution(jobInstance, executionInstanceData.execution.getExecutionId(), this);
        flowExecution.setBatchStatus(batchStatus.name());
        flowExecution.setCreateTime(now);
        flowExecution.setLastUpdateTime(now);
        return flowExecution;
    }

    @Override
    public StepExecution getStepExecutionByStepExecutionId(final long stepExecId) {
        return data.stepExecutionInstanceData.get(stepExecId).execution;
    }

    @Override
    public void cleanUp(final long instanceId) {
        final Structures.JobInstanceData jobInstanceData = data.jobInstanceData.remove(instanceId);
        if (jobInstanceData == null) {
            return;
        }

        synchronized (jobInstanceData.executions) {
            for (final Structures.ExecutionInstanceData executionInstanceData : jobInstanceData.executions) {
                data.executionInstanceData.remove(executionInstanceData.execution.getExecutionId());
                synchronized (executionInstanceData.stepExecutions) {
                    for (final StepExecution stepExecution : executionInstanceData.stepExecutions) {
                        data.stepExecutionInstanceData.remove(stepExecution.getStepExecutionId());
                    }
                }
            }
        }
        synchronized (jobInstanceData.checkpoints) {
            for (final CheckpointDataKey key : jobInstanceData.checkpoints) {
                data.checkpointData.remove(key);
            }
        }
    }

    @Override
    public void cleanUp(final Date until) {
        final Collection<Long> instanceIdToRemove = new ArrayList<Long>();
        for (final Map.Entry<Long, Structures.JobInstanceData> entry : data.jobInstanceData.entrySet()) {
            boolean match = true;
            for (final Structures.ExecutionInstanceData exec : entry.getValue().executions) {
                if (exec.execution.getEndTime() == null || exec.execution.getEndTime().after(until)) {
                    match = false;
                    break;
                }
            }
            if (match) {
                instanceIdToRemove.add(entry.getKey());
            }
        }

        for (final Long id : instanceIdToRemove) {
            cleanUp(id);
        }
    }

    private static class ReverseDateComparator implements Comparator<Date> {
        public static final ReverseDateComparator INSTANCE = new ReverseDateComparator();

        @Override
        public int compare(final Date o1, final Date o2) {
            return o2.compareTo(o1);
        }
    }

    @Override
    public String toString() {
        return getClass().getName();
    }
}
