/*
 * Copyright 2015-present Open Networking Laboratory
 *
 * 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.onlab.stc;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.onlab.stc.Coordinator.Status;

import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.onlab.stc.Coordinator.Status.*;
import static org.onlab.stc.Coordinator.print;

/**
 * Maintains state of scenario execution.
 */
class ScenarioStore {

    private final ProcessFlow processFlow;
    private final File storeFile;
    private final File logDir;

    private final List<StepEvent> events = Lists.newArrayList();
    private final Map<String, Status> statusMap = Maps.newConcurrentMap();

    private long startTime = Long.MAX_VALUE;
    private long endTime = Long.MIN_VALUE;

    /**
     * Creates a new scenario store for the specified process flow.
     *
     * @param processFlow scenario process flow
     * @param logDir      scenario log directory
     * @param name        scenario name
     */
    ScenarioStore(ProcessFlow processFlow, File logDir, String name) {
        this.processFlow = processFlow;
        this.logDir = logDir;
        this.storeFile = new File(logDir, name + ".stc");
        load();
    }

    /**
     * Resets status of all steps to waiting and clears all events.
     */
    void reset() {
        events.clear();
        statusMap.clear();
        processFlow.getVertexes().forEach(step -> statusMap.put(step.name(), WAITING));
        try {
            removeLogs();
            PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile);
            cfg.clear();
            cfg.save();
            startTime = Long.MAX_VALUE;
            endTime = Long.MIN_VALUE;
        } catch (ConfigurationException e) {
            print("Unable to store file %s", storeFile);
        }

    }

    /**
     * Returns set of all test steps.
     *
     * @return set of steps
     */
    Set<Step> getSteps() {
        return processFlow.getVertexes();
    }

    /**
     * Returns a chronological list of step or group records.
     *
     * @return list of events
     */
    synchronized List<StepEvent> getEvents() {
        return ImmutableList.copyOf(events);
    }

    /**
     * Returns the status record of the specified test step.
     *
     * @param step test step or group
     * @return step status record
     */
    Status getStatus(Step step) {
        return checkNotNull(statusMap.get(step.name()), "Step %s not found", step.name());
    }

    /**
     * Marks the specified test step as being in progress.
     *
     * @param step test step or group
     */
    synchronized void markStarted(Step step) {
        add(new StepEvent(step.name(), IN_PROGRESS, step.command()));
        save();
    }

    /**
     * Marks the specified test step as being complete.
     *
     * @param step   test step or group
     * @param status new step status
     */
    synchronized void markComplete(Step step, Status status) {
        add(new StepEvent(step.name(), status, null));
        save();
    }

    /**
     * Returns true if all steps in the store have been marked as completed
     * regardless of the completion status.
     *
     * @return true if all steps completed one way or another
     */
    synchronized boolean isComplete() {
        return !statusMap.values().stream().anyMatch(s -> s == WAITING || s == IN_PROGRESS);
    }

    /**
     * Indicates whether there are any failures.
     *
     * @return true if there are failed steps
     */
    boolean hasFailures() {
        for (Status status : statusMap.values()) {
            if (status == FAILED) {
                return true;
            }
        }
        return false;
    }

    /**
     * Registers a new step record.
     *
     * @param event step event
     */
    private synchronized void add(StepEvent event) {
        events.add(event);
        statusMap.put(event.name(), event.status());
        startTime = Math.min(startTime, event.time());
        endTime = Math.max(endTime, event.time());
    }

    /**
     * Loads the states from disk.
     */
    private void load() {
        try {
            PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile);
            cfg.getKeys().forEachRemaining(prop -> add(StepEvent.fromString(cfg.getString(prop))));
            cfg.save();
        } catch (ConfigurationException e) {
            print("Unable to load file %s", storeFile);
        }
    }

    /**
     * Saves the states to disk.
     */
    private void save() {
        try {
            PropertiesConfiguration cfg = new PropertiesConfiguration(storeFile);
            events.forEach(event -> cfg.setProperty("T" + event.time(), event.toString()));
            cfg.save();
        } catch (ConfigurationException e) {
            print("Unable to store file %s", storeFile);
        }
    }

    /**
     * Removes all scenario log files.
     */
    private void removeLogs() {
        File[] logFiles = logDir.listFiles();
        if (logFiles != null && logFiles.length > 0) {
            for (File file : logFiles) {
                if (!file.delete()) {
                    print("Unable to delete log file %s", file);
                }
            }
        }
    }

    /**
     * Returns the scenario run start time.
     *
     * @return start time in mills since start of epoch
     */
    public long startTime() {
        return startTime;
    }

    /**
     * Returns the scenario run end time or current time if the scenario
     * is still running.
     *
     * @return end time (or current time) in mills since start of epoch
     */
    public long endTime() {
        return endTime > 0 ? endTime : System.currentTimeMillis();
    }
}
