/**
 * 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.internal.telephony;

import android.telephony.Rlog;
import android.util.Pair;
import android.text.TextUtils;

import java.util.Random;
import java.util.ArrayList;

/**
 * Retry manager allows a simple way to declare a series of
 * retry timeouts. After creating a RetryManager the configure
 * method is used to define the sequence. A simple linear series
 * may be initialized using configure with three integer parameters
 * The other configure method allows a series to be declared using
 * a string.
 *<p>
 * The format of the configuration string is a series of parameters
 * separated by a comma. There are two name value pair parameters plus a series
 * of delay times. The units of of these delay times is unspecified.
 * The name value pairs which may be specified are:
 *<ul>
 *<li>max_retries=<value>
 *<li>default_randomizationTime=<value>
 *</ul>
 *<p>
 * max_retries is the number of times that incrementRetryCount
 * maybe called before isRetryNeeded will return false. if value
 * is infinite then isRetryNeeded will always return true.
 *
 * default_randomizationTime will be used as the randomizationTime
 * for delay times which have no supplied randomizationTime. If
 * default_randomizationTime is not defined it defaults to 0.
 *<p>
 * The other parameters define The series of delay times and each
 * may have an optional randomization value separated from the
 * delay time by a colon.
 *<p>
 * Examples:
 * <ul>
 * <li>3 retries with no randomization value which means its 0:
 * <ul><li><code>"1000, 2000, 3000"</code></ul>
 *
 * <li>10 retries with a 500 default randomization value for each and
 * the 4..10 retries all using 3000 as the delay:
 * <ul><li><code>"max_retries=10, default_randomization=500, 1000, 2000, 3000"</code></ul>
 *
 * <li>4 retries with a 100 as the default randomization value for the first 2 values and
 * the other two having specified values of 500:
 * <ul><li><code>"default_randomization=100, 1000, 2000, 4000:500, 5000:500"</code></ul>
 *
 * <li>Infinite number of retries with the first one at 1000, the second at 2000 all
 * others will be at 3000.
 * <ul><li><code>"max_retries=infinite,1000,2000,3000</code></ul>
 * </ul>
 *
 * {@hide}
 */
public class RetryManager {
    static public final String LOG_TAG = "RetryManager";
    static public final boolean DBG = false;
    static public final boolean VDBG = false;

    /**
     * Retry record with times in milli-seconds
     */
    private static class RetryRec {
        RetryRec(int delayTime, int randomizationTime) {
            mDelayTime = delayTime;
            mRandomizationTime = randomizationTime;
        }

        int mDelayTime;
        int mRandomizationTime;
    }

    /** The array of retry records */
    private ArrayList<RetryRec> mRetryArray = new ArrayList<RetryRec>();

    /** When true isRetryNeeded() will always return true */
    private boolean mRetryForever;

    /**
     * The maximum number of retries to attempt before
     * isRetryNeeded returns false
     */
    private int mMaxRetryCount;

    private int mCurMaxRetryCount;

    /** The current number of retries */
    private int mRetryCount;

    /** Random number generator */
    private Random mRng = new Random();

    private String mConfig;

    /** Constructor */
    public RetryManager() {
        if (VDBG) log("constructor");
    }

    @Override
    public String toString() {
        String ret = "RetryManager: { forever=" + mRetryForever + " maxRetry=" + mMaxRetryCount
                + " curMaxRetry=" + mCurMaxRetryCount + " retry=" + mRetryCount
                + " config={" + mConfig + "} retryArray={";
        for (RetryRec r : mRetryArray) {
            ret += r.mDelayTime + ":" + r.mRandomizationTime + " ";
        }
        ret += "}}";
        return ret;
    }

    /**
     * Configure for a simple linear sequence of times plus
     * a random value.
     *
     * @param maxRetryCount is the maximum number of retries
     *        before isRetryNeeded returns false.
     * @param retryTime is a time that will be returned by getRetryTime.
     * @param randomizationTime a random value between 0 and
     *        randomizationTime will be added to retryTime. this
     *        parameter may be 0.
     * @return true if successful
     */
    public boolean configure(int maxRetryCount, int retryTime, int randomizationTime) {
        Pair<Boolean, Integer> value;

        if (VDBG) log("configure: " + maxRetryCount + ", " + retryTime + "," + randomizationTime);

        if (!validateNonNegativeInt("maxRetryCount", maxRetryCount)) {
            return false;
        }

        if (!validateNonNegativeInt("retryTime", retryTime)) {
            return false;
        }

        if (!validateNonNegativeInt("randomizationTime", randomizationTime)) {
            return false;
        }

        mMaxRetryCount = maxRetryCount;
        mCurMaxRetryCount = mMaxRetryCount;

        resetRetryCount();
        mRetryArray.clear();
        mRetryArray.add(new RetryRec(retryTime, randomizationTime));

        return true;
    }

    /**
     * Configure for using string which allow arbitrary
     * sequences of times. See class comments for the
     * string format.
     *
     * @return true if successful
     */
    public boolean configure(String configStr) {
        // Strip quotes if present.
        if ((configStr.startsWith("\"") && configStr.endsWith("\""))) {
            configStr = configStr.substring(1, configStr.length()-1);
        }
        if (VDBG) log("configure: '" + configStr + "'");
        mConfig = configStr;

        if (!TextUtils.isEmpty(configStr)) {
            int defaultRandomization = 0;

            if (VDBG) log("configure: not empty");

            mMaxRetryCount = 0;
            resetRetryCount();
            mRetryArray.clear();

            String strArray[] = configStr.split(",");
            for (int i = 0; i < strArray.length; i++) {
                if (VDBG) log("configure: strArray[" + i + "]='" + strArray[i] + "'");
                Pair<Boolean, Integer> value;
                String splitStr[] = strArray[i].split("=", 2);
                splitStr[0] = splitStr[0].trim();
                if (VDBG) log("configure: splitStr[0]='" + splitStr[0] + "'");
                if (splitStr.length > 1) {
                    splitStr[1] = splitStr[1].trim();
                    if (VDBG) log("configure: splitStr[1]='" + splitStr[1] + "'");
                    if (TextUtils.equals(splitStr[0], "default_randomization")) {
                        value = parseNonNegativeInt(splitStr[0], splitStr[1]);
                        if (!value.first) return false;
                        defaultRandomization = value.second;
                    } else if (TextUtils.equals(splitStr[0], "max_retries")) {
                        if (TextUtils.equals("infinite",splitStr[1])) {
                            mRetryForever = true;
                        } else {
                            value = parseNonNegativeInt(splitStr[0], splitStr[1]);
                            if (!value.first) return false;
                            mMaxRetryCount = value.second;
                        }
                    } else {
                        Rlog.e(LOG_TAG, "Unrecognized configuration name value pair: "
                                        + strArray[i]);
                        return false;
                    }
                } else {
                    /**
                     * Assume a retry time with an optional randomization value
                     * following a ":"
                     */
                    splitStr = strArray[i].split(":", 2);
                    splitStr[0] = splitStr[0].trim();
                    RetryRec rr = new RetryRec(0, 0);
                    value = parseNonNegativeInt("delayTime", splitStr[0]);
                    if (!value.first) return false;
                    rr.mDelayTime = value.second;

                    // Check if optional randomization value present
                    if (splitStr.length > 1) {
                        splitStr[1] = splitStr[1].trim();
                        if (VDBG) log("configure: splitStr[1]='" + splitStr[1] + "'");
                        value = parseNonNegativeInt("randomizationTime", splitStr[1]);
                        if (!value.first) return false;
                        rr.mRandomizationTime = value.second;
                    } else {
                        rr.mRandomizationTime = defaultRandomization;
                    }
                    mRetryArray.add(rr);
                }
            }
            if (mRetryArray.size() > mMaxRetryCount) {
                mMaxRetryCount = mRetryArray.size();
                if (VDBG) log("configure: setting mMaxRetryCount=" + mMaxRetryCount);
            }
            mCurMaxRetryCount = mMaxRetryCount;
            if (VDBG) log("configure: true");
            return true;
        } else {
            if (VDBG) log("configure: false it's empty");
            return false;
        }
    }

    /**
     * Report whether data reconnection should be retried
     *
     * @return {@code true} if the max retries has not been reached. {@code
     *         false} otherwise.
     */
    public boolean isRetryNeeded() {
        boolean retVal = mRetryForever || (mRetryCount < mCurMaxRetryCount);
        if (DBG) log("isRetryNeeded: " + retVal);
        return retVal;
    }

    /**
     * Return the timer that should be used to trigger the data reconnection
     */
    public int getRetryTimer() {
        int index;
        if (mRetryCount < mRetryArray.size()) {
            index = mRetryCount;
        } else {
            index = mRetryArray.size() - 1;
        }

        int retVal;
        if ((index >= 0) && (index < mRetryArray.size())) {
            retVal = mRetryArray.get(index).mDelayTime + nextRandomizationTime(index);
        } else {
            retVal = 0;
        }

        if (DBG) log("getRetryTimer: " + retVal);
        return retVal;
    }

    /**
     * @return retry count
     */
    public int getRetryCount() {
        if (DBG) log("getRetryCount: " + mRetryCount);
        return mRetryCount;
    }

    /**
     * Increase the retry counter, does not change retry forever.
     */
    public void increaseRetryCount() {
        mRetryCount++;
        if (mRetryCount > mCurMaxRetryCount) {
            mRetryCount = mCurMaxRetryCount;
        }
        if (DBG) log("increaseRetryCount: " + mRetryCount);
    }

    /**
     * Set retry count to the specified value
     */
    public void setRetryCount(int count) {
        mRetryCount = count;
        if (mRetryCount > mCurMaxRetryCount) {
            mRetryCount = mCurMaxRetryCount;
        }

        if (mRetryCount < 0) {
            mRetryCount = 0;
        }

        if (DBG) log("setRetryCount: " + mRetryCount);
    }

    /**
     * Set current maximum retry count to the specified value
     */
    public void setCurMaxRetryCount(int count) {
        mCurMaxRetryCount = count;

        // Make sure it's not negative
        if (mCurMaxRetryCount < 0) {
            mCurMaxRetryCount = 0;
        }

        // Make sure mRetryCount is within range
        setRetryCount(mRetryCount);

        if (DBG) log("setCurMaxRetryCount: " + mCurMaxRetryCount);
    }

    /**
     * Restore CurMaxRetryCount
     */
    public void restoreCurMaxRetryCount() {
        mCurMaxRetryCount = mMaxRetryCount;

        // Make sure mRetryCount is within range
        setRetryCount(mRetryCount);
    }

    /**
     * Set retry forever to the specified value
     */
    public void setRetryForever(boolean retryForever) {
        mRetryForever = retryForever;
        if (DBG) log("setRetryForever: " + mRetryForever);
    }

    /**
     * Clear the data-retry counter
     */
    public void resetRetryCount() {
        mRetryCount = 0;
        if (DBG) log("resetRetryCount: " + mRetryCount);
    }

    /**
     * Retry forever using last timeout time.
     */
    public void retryForeverUsingLastTimeout() {
        mRetryCount = mCurMaxRetryCount;
        mRetryForever = true;
        if (DBG) log("retryForeverUsingLastTimeout: " + mRetryForever + ", " + mRetryCount);
    }

    /**
     * @return true if retrying forever
     */
    public boolean isRetryForever() {
        if (DBG) log("isRetryForever: " + mRetryForever);
        return mRetryForever;
    }

    /**
     * Parse an integer validating the value is not negative.
     *
     * @param name
     * @param stringValue
     * @return Pair.first == true if stringValue an integer >= 0
     */
    private Pair<Boolean, Integer> parseNonNegativeInt(String name, String stringValue) {
        int value;
        Pair<Boolean, Integer> retVal;
        try {
            value = Integer.parseInt(stringValue);
            retVal = new Pair<Boolean, Integer>(validateNonNegativeInt(name, value), value);
        } catch (NumberFormatException e) {
            Rlog.e(LOG_TAG, name + " bad value: " + stringValue, e);
            retVal = new Pair<Boolean, Integer>(false, 0);
        }
        if (VDBG) log("parseNonNetativeInt: " + name + ", " + stringValue + ", "
                    + retVal.first + ", " + retVal.second);
        return retVal;
    }

    /**
     * Validate an integer is >= 0 and logs an error if not
     *
     * @param name
     * @param value
     * @return Pair.first
     */
    private boolean validateNonNegativeInt(String name, int value) {
        boolean retVal;
        if (value < 0) {
            Rlog.e(LOG_TAG, name + " bad value: is < 0");
            retVal = false;
        } else {
            retVal = true;
        }
        if (VDBG) log("validateNonNegative: " + name + ", " + value + ", " + retVal);
        return retVal;
    }

    /**
     * Return next random number for the index
     */
    private int nextRandomizationTime(int index) {
        int randomTime = mRetryArray.get(index).mRandomizationTime;
        if (randomTime == 0) {
            return 0;
        } else {
            return mRng.nextInt(randomTime);
        }
    }

    private void log(String s) {
        Rlog.d(LOG_TAG, "[RM] " + s);
    }
}
