/*
 * 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.wayang.commons.util.profiledb.model.measurement;

import org.apache.wayang.commons.util.profiledb.model.Measurement;
import org.apache.wayang.commons.util.profiledb.model.Type;

import java.util.Collection;
import java.util.LinkedList;

/**
 * A {@link Measurement} that captures a certain amount of time in milliseconds. Instances can be nested within
 * each other.
 * <p>Besides storing those data, it also provides utility functionality to obtain measurements.</p>
 */
@Type("time")
public class TimeMeasurement extends Measurement {

    /**
     * The measured time in milliseconds.
     */
    private long millis = 0L;

    /**
     * Keeps track on measurement starts.
     */
    private transient long startTime = -1L;

    /**
     * Sub-{@link TimeMeasurement}s of this instance.
     */
    private Collection<TimeMeasurement> rounds = new LinkedList<>();

    /**
     * Serialization constructor.
     */
    @SuppressWarnings("unused")
    private TimeMeasurement() {
        super();
    }

    /**
     * Creates a new instance.
     *
     * @param id the ID of the new instance
     */
    public TimeMeasurement(String id) {
        super(id);
    }

    /**
     * Start measuring time for this instance.
     */
    public void start() {
        this.startTime = System.currentTimeMillis();
    }

    /**
     * Ensure that this instance has its timer started.
     */
    private void ensureStarted() {
        if (this.startTime == -1L) {
            this.startTime = System.currentTimeMillis();
        }
    }

    /**
     * Start a (potentially new) sub-{@link TimeMeasurement}.
     *
     * @param identifiers identifies the target {@link TimeMeasurement} as a path of IDs
     * @return the started instance
     */
    public TimeMeasurement start(String... identifiers) {
        return this.start(identifiers, 0);
    }

    /**
     * Start a (potentially new) sub-{@link TimeMeasurement}.
     *
     * @param identifiers identifies the target {@link TimeMeasurement} as a path of IDs
     * @param index       the index of this instance within {@code identifiers}
     * @return the started instance
     */
    private TimeMeasurement start(String[] identifiers, int index) {
        if (index >= identifiers.length) {
            this.start();
            return this;
        } else {
            this.ensureStarted();
            TimeMeasurement round = this.getOrCreateRound(identifiers[index]);
            return round.start(identifiers, index + 1);
        }
    }

    /**
     * Retrieves an existing {@link TimeMeasurement} from {@link #rounds} with the given {@code id} or creates and stores a new one.
     *
     * @param id the ID of the {@link TimeMeasurement}
     * @return the {@link TimeMeasurement}
     */
    public TimeMeasurement getOrCreateRound(String id) {
        TimeMeasurement round = this.getRound(id);
        if (round != null) return round;

        round = new TimeMeasurement(id);
        this.rounds.add(round);
        return round;
    }

    /**
     * Retrieves an existing {@link TimeMeasurement} from {@link #rounds} with the given {@code id}.
     *
     * @param id the ID of the {@link TimeMeasurement}
     * @return the {@link TimeMeasurement} or {@code null} if it does not exist
     */
    private TimeMeasurement getRound(String id) {
        for (TimeMeasurement round : this.rounds) {
            if (id.equals(round.getId())) {
                return round;
            }
        }
        return null;
    }

    /**
     * Stop a measurement that has been started via {@link #start()} or derivatives.
     */
    public void stop() {
        this.stop(System.currentTimeMillis());
    }


    /**
     * Stop a measurement that has been started via {@link #start()} or derivatives.
     *
     * @param stopTime at which the measurement has been stopped
     */
    private void stop(long stopTime) {
        if (this.startTime != -1L) {
            this.millis += (stopTime - this.startTime);
            this.startTime = -1L;
        }
        for (TimeMeasurement round : this.rounds) {
            round.stop(stopTime);
        }
    }

    /**
     * Stop a measurement that has been started via {@link #start(String...)} or related.
     *
     * @param identfiers identify the target {@link TimeMeasurement} as a path of IDs
     */
    public void stop(String... identfiers) {
        long stopTime = System.currentTimeMillis();
        TimeMeasurement round = this;
        for (String identfier : identfiers) {
            round = round.getRound(identfier);
            if (round == null) return;
        }
        round.stop(stopTime);
    }

    public long getMillis() {
        return millis;
    }

    public void setMillis(long millis) {
        this.millis = millis;
    }

    public Collection<TimeMeasurement> getRounds() {
        return rounds;
    }

    public void addRounds(TimeMeasurement round) {
        this.rounds.add(round);
    }

    /**
     * Formats the given milliseconds as {@code h:MM:ss.mmm}.
     *
     * @param millis the milliseconds to format
     * @return the formatted milliseconds
     */
    public static String formatDuration(long millis) {
        if (millis < 0) return "-" + formatDuration(-millis);
        long ms = millis % 1000;
        millis /= 1000;
        long s = millis % 60;
        millis /= 60;
        long m = millis % 60;
        millis /= 60;
        long h = millis % 60;
        return String.format("%d:%02d:%02d.%03d", h, m, s, ms);
    }

    @Override
    public String toString() {
        return String.format("%s[%s, %s, %d subs]", this.getClass().getSimpleName(), this.getId(), formatDuration(this.millis), this.rounds.size());
    }
}
