/*
 * Copyright (C) 2009 The Android Open Source Project
 *
 * 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 com.android.common;

import android.content.SharedPreferences;
import android.text.format.Time;

import java.util.Map;
import java.util.TreeMap;

/**
 * Tracks the success/failure history of a particular network operation in
 * persistent storage and computes retry strategy accordingly.  Handles
 * exponential backoff, periodic rescheduling, event-driven triggering,
 * retry-after moratorium intervals, etc. based on caller-specified parameters.
 *
 * <p>This class does not directly perform or invoke any operations,
 * it only keeps track of the schedule.  Somebody else needs to call
 * {@link #getNextTimeMillis} as appropriate and do the actual work.
 */
public class OperationScheduler {
    /** Tunable parameter options for {@link #getNextTimeMillis}. */
    public static class Options {
        /** Wait this long after every error before retrying. */
        public long backoffFixedMillis = 0;

        /** Wait this long times the number of consecutive errors so far before retrying. */
        public long backoffIncrementalMillis = 5000;

        /** Wait this long times 2^(number of consecutive errors so far) before retrying. */
        public int backoffExponentialMillis = 0;

        /** Maximum duration of moratorium to honor.  Mostly an issue for clock rollbacks. */
        public long maxMoratoriumMillis = 24 * 3600 * 1000;

        /** Minimum duration after success to wait before allowing another trigger. */
        public long minTriggerMillis = 0;

        /** Automatically trigger this long after the last success. */
        public long periodicIntervalMillis = 0;

        @Override
        public String toString() {
            if (backoffExponentialMillis > 0) {
                return String.format(
                    "OperationScheduler.Options[backoff=%.1f+%.1f+%.1f max=%.1f min=%.1f period=%.1f]",
                    backoffFixedMillis / 1000.0, backoffIncrementalMillis / 1000.0,
                    backoffExponentialMillis / 1000.0,
                    maxMoratoriumMillis / 1000.0, minTriggerMillis / 1000.0,
                    periodicIntervalMillis / 1000.0);
            } else {
                return String.format(
                    "OperationScheduler.Options[backoff=%.1f+%.1f max=%.1f min=%.1f period=%.1f]",
                    backoffFixedMillis / 1000.0, backoffIncrementalMillis / 1000.0,
                    maxMoratoriumMillis / 1000.0, minTriggerMillis / 1000.0,
                    periodicIntervalMillis / 1000.0);
            }
        }
    }

    private static final String PREFIX = "OperationScheduler_";
    private final SharedPreferences mStorage;

    /**
     * Initialize the scheduler state.
     * @param storage to use for recording the state of operations across restarts/reboots
     */
    public OperationScheduler(SharedPreferences storage) {
        mStorage = storage;
    }

    /**
     * Parse scheduler options supplied in this string form:
     *
     * <pre>
     * backoff=(fixed)+(incremental)[+(exponential)] max=(maxmoratorium) min=(mintrigger) [period=](interval)
     * </pre>
     *
     * All values are times in (possibly fractional) <em>seconds</em> (not milliseconds).
     * Omitted settings are left at whatever existing default value was passed in.
     *
     * <p>
     * The default options: <code>backoff=0+5 max=86400 min=0 period=0</code><br>
     * Fractions are OK: <code>backoff=+2.5 period=10.0</code><br>
     * The "period=" can be omitted: <code>3600</code><br>
     *
     * @param spec describing some or all scheduler options.
     * @param options to update with parsed values.
     * @return the options passed in (for convenience)
     * @throws IllegalArgumentException if the syntax is invalid
     */
    public static Options parseOptions(String spec, Options options)
            throws IllegalArgumentException {
        for (String param : spec.split(" +")) {
            if (param.length() == 0) continue;
            if (param.startsWith("backoff=")) {
                String[] pieces = param.substring(8).split("\\+");
                if (pieces.length > 3) {
                    throw new IllegalArgumentException("bad value for backoff: [" + spec + "]");
                }
                if (pieces.length > 0 && pieces[0].length() > 0) {
                    options.backoffFixedMillis = parseSeconds(pieces[0]);
                }
                if (pieces.length > 1 && pieces[1].length() > 0) {
                    options.backoffIncrementalMillis = parseSeconds(pieces[1]);
                }
                if (pieces.length > 2 && pieces[2].length() > 0) {
                    options.backoffExponentialMillis = (int)parseSeconds(pieces[2]);
                }
            } else if (param.startsWith("max=")) {
                options.maxMoratoriumMillis = parseSeconds(param.substring(4));
            } else if (param.startsWith("min=")) {
                options.minTriggerMillis = parseSeconds(param.substring(4));
            } else if (param.startsWith("period=")) {
                options.periodicIntervalMillis = parseSeconds(param.substring(7));
            } else {
                options.periodicIntervalMillis = parseSeconds(param);
            }
        }
        return options;
    }

    private static long parseSeconds(String param) throws NumberFormatException {
        return (long) (Float.parseFloat(param) * 1000);
    }

    /**
     * Compute the time of the next operation.  Does not modify any state
     * (unless the clock rolls backwards, in which case timers are reset).
     *
     * @param options to use for this computation.
     * @return the wall clock time ({@link System#currentTimeMillis()}) when the
     * next operation should be attempted -- immediately, if the return value is
     * before the current time.
     */
    public long getNextTimeMillis(Options options) {
        boolean enabledState = mStorage.getBoolean(PREFIX + "enabledState", true);
        if (!enabledState) return Long.MAX_VALUE;

        boolean permanentError = mStorage.getBoolean(PREFIX + "permanentError", false);
        if (permanentError) return Long.MAX_VALUE;

        // We do quite a bit of limiting to prevent a clock rollback from totally
        // hosing the scheduler.  Times which are supposed to be in the past are
        // clipped to the current time so we don't languish forever.

        int errorCount = mStorage.getInt(PREFIX + "errorCount", 0);
        long now = currentTimeMillis();
        long lastSuccessTimeMillis = getTimeBefore(PREFIX + "lastSuccessTimeMillis", now);
        long lastErrorTimeMillis = getTimeBefore(PREFIX + "lastErrorTimeMillis", now);
        long triggerTimeMillis = mStorage.getLong(PREFIX + "triggerTimeMillis", Long.MAX_VALUE);
        long moratoriumSetMillis = getTimeBefore(PREFIX + "moratoriumSetTimeMillis", now);
        long moratoriumTimeMillis = getTimeBefore(PREFIX + "moratoriumTimeMillis",
                moratoriumSetMillis + options.maxMoratoriumMillis);

        long time = triggerTimeMillis;
        if (options.periodicIntervalMillis > 0) {
            time = Math.min(time, lastSuccessTimeMillis + options.periodicIntervalMillis);
        }

        time = Math.max(time, moratoriumTimeMillis);
        time = Math.max(time, lastSuccessTimeMillis + options.minTriggerMillis);
        if (errorCount > 0) {
            int shift = errorCount-1;
            // backoffExponentialMillis is an int, so we can safely
            // double it 30 times without overflowing a long.
            if (shift > 30) shift = 30;
            long backoff = options.backoffFixedMillis +
                (options.backoffIncrementalMillis * errorCount) +
                (((long)options.backoffExponentialMillis) << shift);

            // Treat backoff like a moratorium: don't let the backoff time grow too large.
            backoff = Math.min(backoff, options.maxMoratoriumMillis);

            time = Math.max(time, lastErrorTimeMillis + backoff);
        }
        return time;
    }

    /**
     * Return the last time the operation completed.  Does not modify any state.
     *
     * @return the wall clock time when {@link #onSuccess()} was last called.
     */
    public long getLastSuccessTimeMillis() {
        return mStorage.getLong(PREFIX + "lastSuccessTimeMillis", 0);
    }

    /**
     * Return the last time the operation was attempted.  Does not modify any state.
     *
     * @return the wall clock time when {@link #onSuccess()} or {@link
     * #onTransientError()} was last called.
     */
    public long getLastAttemptTimeMillis() {
        return Math.max(
                mStorage.getLong(PREFIX + "lastSuccessTimeMillis", 0),
                mStorage.getLong(PREFIX + "lastErrorTimeMillis", 0));
    }

    /**
     * Fetch a {@link SharedPreferences} property, but force it to be before
     * a certain time, updating the value if necessary.  This is to recover
     * gracefully from clock rollbacks which could otherwise strand our timers.
     *
     * @param name of SharedPreferences key
     * @param max time to allow in result
     * @return current value attached to key (default 0), limited by max
     */
    private long getTimeBefore(String name, long max) {
        long time = mStorage.getLong(name, 0);
        if (time > max) {
            time = max;
            SharedPreferencesCompat.apply(mStorage.edit().putLong(name, time));
        }
        return time;
    }

    /**
     * Request an operation to be performed at a certain time.  The actual
     * scheduled time may be affected by error backoff logic and defined
     * minimum intervals.  Use {@link Long#MAX_VALUE} to disable triggering.
     *
     * @param millis wall clock time ({@link System#currentTimeMillis()}) to
     * trigger another operation; 0 to trigger immediately
     */
    public void setTriggerTimeMillis(long millis) {
        SharedPreferencesCompat.apply(
                mStorage.edit().putLong(PREFIX + "triggerTimeMillis", millis));
    }

    /**
     * Forbid any operations until after a certain (absolute) time.
     * Limited by {@link Options#maxMoratoriumMillis}.
     *
     * @param millis wall clock time ({@link System#currentTimeMillis()})
     * when operations should be allowed again; 0 to remove moratorium
     */
    public void setMoratoriumTimeMillis(long millis) {
        SharedPreferencesCompat.apply(mStorage.edit()
                   .putLong(PREFIX + "moratoriumTimeMillis", millis)
                   .putLong(PREFIX + "moratoriumSetTimeMillis", currentTimeMillis()));
    }

    /**
     * Forbid any operations until after a certain time, as specified in
     * the format used by the HTTP "Retry-After" header.
     * Limited by {@link Options#maxMoratoriumMillis}.
     *
     * @param retryAfter moratorium time in HTTP format
     * @return true if a time was successfully parsed
     */
    public boolean setMoratoriumTimeHttp(String retryAfter) {
        try {
            long ms = Long.parseLong(retryAfter) * 1000;
            setMoratoriumTimeMillis(ms + currentTimeMillis());
            return true;
        } catch (NumberFormatException nfe) {
            try {
                setMoratoriumTimeMillis(LegacyHttpDateTime.parse(retryAfter));
                return true;
            } catch (IllegalArgumentException iae) {
                return false;
            }
        }
    }

    /**
     * Enable or disable all operations.  When disabled, all calls to
     * {@link #getNextTimeMillis} return {@link Long#MAX_VALUE}.
     * Commonly used when data network availability goes up and down.
     *
     * @param enabled if operations can be performed
     */
    public void setEnabledState(boolean enabled) {
        SharedPreferencesCompat.apply(
                mStorage.edit().putBoolean(PREFIX + "enabledState", enabled));
    }

    /**
     * Report successful completion of an operation.  Resets all error
     * counters, clears any trigger directives, and records the success.
     */
    public void onSuccess() {
        resetTransientError();
        resetPermanentError();
        SharedPreferencesCompat.apply(mStorage.edit()
                .remove(PREFIX + "errorCount")
                .remove(PREFIX + "lastErrorTimeMillis")
                .remove(PREFIX + "permanentError")
                .remove(PREFIX + "triggerTimeMillis")
                .putLong(PREFIX + "lastSuccessTimeMillis", currentTimeMillis()));
    }

    /**
     * Report a transient error (usually a network failure).  Increments
     * the error count and records the time of the latest error for backoff
     * purposes.
     */
    public void onTransientError() {
        SharedPreferences.Editor editor = mStorage.edit();
        editor.putLong(PREFIX + "lastErrorTimeMillis", currentTimeMillis());
        editor.putInt(PREFIX + "errorCount",
                mStorage.getInt(PREFIX + "errorCount", 0) + 1);
        SharedPreferencesCompat.apply(editor);
    }

    /**
     * Reset all transient error counts, allowing the next operation to proceed
     * immediately without backoff.  Commonly used on network state changes, when
     * partial progress occurs (some data received), and in other circumstances
     * where there is reason to hope things might start working better.
     */
    public void resetTransientError() {
        SharedPreferencesCompat.apply(mStorage.edit().remove(PREFIX + "errorCount"));
    }

    /**
     * Report a permanent error that will not go away until further notice.
     * No operation will be scheduled until {@link #resetPermanentError()}
     * is called.  Commonly used for authentication failures (which are reset
     * when the accounts database is updated).
     */
    public void onPermanentError() {
        SharedPreferencesCompat.apply(mStorage.edit().putBoolean(PREFIX + "permanentError", true));
    }

    /**
     * Reset any permanent error status set by {@link #onPermanentError},
     * allowing operations to be scheduled as normal.
     */
    public void resetPermanentError() {
        SharedPreferencesCompat.apply(mStorage.edit().remove(PREFIX + "permanentError"));
    }

    /**
     * Return a string description of the scheduler state for debugging.
     */
    public String toString() {
        StringBuilder out = new StringBuilder("[OperationScheduler:");
        TreeMap<String, Object> copy = new TreeMap<String, Object>(mStorage.getAll());  // Sort keys
        for (Map.Entry<String, Object> e : copy.entrySet()) {
            String key = e.getKey();
            if (key.startsWith(PREFIX)) {
                if (key.endsWith("TimeMillis")) {
                    Time time = new Time();
                    time.set((Long) e.getValue());
                    out.append(" ").append(key.substring(PREFIX.length(), key.length() - 10));
                    out.append("=").append(time.format("%Y-%m-%d/%H:%M:%S"));
                } else {
                    out.append(" ").append(key.substring(PREFIX.length()));
                    Object v = e.getValue();
                    if (v == null) {
                        out.append("=(null)");
                    } else {
                        out.append("=").append(v.toString());
                    }
                }
            }
        }
        return out.append("]").toString();
    }

    /**
     * Gets the current time.  Can be overridden for unit testing.
     *
     * @return {@link System#currentTimeMillis()}
     */
    protected long currentTimeMillis() {
        return System.currentTimeMillis();
    }
}
