/*
 * Copyright (C) 2015 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.systemui.statusbar.policy;

import static com.android.systemui.statusbar.policy.NetworkControllerImpl.TAG;

import android.content.Context;
import android.text.format.DateFormat;
import android.util.Log;

import com.android.systemui.statusbar.policy.NetworkController.SignalCallback;

import java.io.PrintWriter;
import java.util.BitSet;


/**
 * Common base class for handling signal for both wifi and mobile data.
 */
public abstract class SignalController<T extends SignalController.State,
        I extends SignalController.IconGroup> {
    // Save the previous SignalController.States of all SignalControllers for dumps.
    static final boolean RECORD_HISTORY = true;
    // If RECORD_HISTORY how many to save, must be a power of 2.
    static final int HISTORY_SIZE = 64;

    protected static final boolean DEBUG = NetworkControllerImpl.DEBUG;
    protected static final boolean CHATTY = NetworkControllerImpl.CHATTY;

    protected final String mTag;
    protected final T mCurrentState;
    protected final T mLastState;
    protected final int mTransportType;
    protected final Context mContext;
    // The owner of the SignalController (i.e. NetworkController will maintain the following
    // lists and call notifyListeners whenever the list has changed to ensure everyone
    // is aware of current state.
    protected final NetworkControllerImpl mNetworkController;

    private final CallbackHandler mCallbackHandler;

    // Save the previous HISTORY_SIZE states for logging.
    private final State[] mHistory;
    // Where to copy the next state into.
    private int mHistoryIndex;

    public SignalController(String tag, Context context, int type, CallbackHandler callbackHandler,
            NetworkControllerImpl networkController) {
        mTag = TAG + "." + tag;
        mNetworkController = networkController;
        mTransportType = type;
        mContext = context;
        mCallbackHandler = callbackHandler;
        mCurrentState = cleanState();
        mLastState = cleanState();
        if (RECORD_HISTORY) {
            mHistory = new State[HISTORY_SIZE];
            for (int i = 0; i < HISTORY_SIZE; i++) {
                mHistory[i] = cleanState();
            }
        }
    }

    public T getState() {
        return mCurrentState;
    }

    public void updateConnectivity(BitSet connectedTransports, BitSet validatedTransports) {
        mCurrentState.inetCondition = validatedTransports.get(mTransportType) ? 1 : 0;
        notifyListenersIfNecessary();
    }

    /**
     * Used at the end of demo mode to clear out any ugly state that it has created.
     * Since we haven't had any callbacks, then isDirty will not have been triggered,
     * so we can just take the last good state directly from there.
     *
     * Used for demo mode.
     */
    public void resetLastState() {
        mCurrentState.copyFrom(mLastState);
    }

    /**
     * Determines if the state of this signal controller has changed and
     * needs to trigger callbacks related to it.
     */
    public boolean isDirty() {
        if (!mLastState.equals(mCurrentState)) {
            if (DEBUG) {
                Log.d(mTag, "Change in state from: " + mLastState + "\n"
                        + "\tto: " + mCurrentState);
            }
            return true;
        }
        return false;
    }

    public void saveLastState() {
        if (RECORD_HISTORY) {
            recordLastState();
        }
        // Updates the current time.
        mCurrentState.time = System.currentTimeMillis();
        mLastState.copyFrom(mCurrentState);
    }

    /**
     * Gets the signal icon for QS based on current state of connected, enabled, and level.
     */
    public int getQsCurrentIconId() {
        if (mCurrentState.connected) {
            return getIcons().mQsIcons[mCurrentState.inetCondition][mCurrentState.level];
        } else if (mCurrentState.enabled) {
            return getIcons().mQsDiscState;
        } else {
            return getIcons().mQsNullState;
        }
    }

    /**
     * Gets the signal icon for SB based on current state of connected, enabled, and level.
     */
    public int getCurrentIconId() {
        if (mCurrentState.connected) {
            return getIcons().mSbIcons[mCurrentState.inetCondition][mCurrentState.level];
        } else if (mCurrentState.enabled) {
            return getIcons().mSbDiscState;
        } else {
            return getIcons().mSbNullState;
        }
    }

    /**
     * Gets the content description id for the signal based on current state of connected and
     * level.
     */
    public int getContentDescription() {
        if (mCurrentState.connected) {
            return getIcons().mContentDesc[mCurrentState.level];
        } else {
            return getIcons().mDiscContentDesc;
        }
    }

    public void notifyListenersIfNecessary() {
        if (isDirty()) {
            saveLastState();
            notifyListeners();
        }
    }

    /**
     * Returns the resource if resId is not 0, and an empty string otherwise.
     */
    protected String getStringIfExists(int resId) {
        return resId != 0 ? mContext.getString(resId) : "";
    }

    protected I getIcons() {
        return (I) mCurrentState.iconGroup;
    }

    /**
     * Saves the last state of any changes, so we can log the current
     * and last value of any state data.
     */
    protected void recordLastState() {
        mHistory[mHistoryIndex++ & (HISTORY_SIZE - 1)].copyFrom(mLastState);
    }

    public void dump(PrintWriter pw) {
        pw.println("  - " + mTag + " -----");
        pw.println("  Current State: " + mCurrentState);
        if (RECORD_HISTORY) {
            // Count up the states that actually contain time stamps, and only display those.
            int size = 0;
            for (int i = 0; i < HISTORY_SIZE; i++) {
                if (mHistory[i].time != 0) size++;
            }
            // Print out the previous states in ordered number.
            for (int i = mHistoryIndex + HISTORY_SIZE - 1;
                    i >= mHistoryIndex + HISTORY_SIZE - size; i--) {
                pw.println("  Previous State(" + (mHistoryIndex + HISTORY_SIZE - i) + "): "
                        + mHistory[i & (HISTORY_SIZE - 1)]);
            }
        }
    }

    public final void notifyListeners() {
        notifyListeners(mCallbackHandler);
    }

    /**
     * Trigger callbacks based on current state.  The callbacks should be completely
     * based on current state, and only need to be called in the scenario where
     * mCurrentState != mLastState.
     */
    public abstract void notifyListeners(SignalCallback callback);

    /**
     * Generate a blank T.
     */
    protected abstract T cleanState();

    /*
     * Holds icons for a given state. Arrays are generally indexed as inet
     * state (full connectivity or not) first, and second dimension as
     * signal strength.
     */
    static class IconGroup {
        final int[][] mSbIcons;
        final int[][] mQsIcons;
        final int[] mContentDesc;
        final int mSbNullState;
        final int mQsNullState;
        final int mSbDiscState;
        final int mQsDiscState;
        final int mDiscContentDesc;
        // For logging.
        final String mName;

        public IconGroup(String name, int[][] sbIcons, int[][] qsIcons, int[] contentDesc,
                int sbNullState, int qsNullState, int sbDiscState, int qsDiscState,
                int discContentDesc) {
            mName = name;
            mSbIcons = sbIcons;
            mQsIcons = qsIcons;
            mContentDesc = contentDesc;
            mSbNullState = sbNullState;
            mQsNullState = qsNullState;
            mSbDiscState = sbDiscState;
            mQsDiscState = qsDiscState;
            mDiscContentDesc = discContentDesc;
        }

        @Override
        public String toString() {
            return "IconGroup(" + mName + ")";
        }
    }

    static class State {
        boolean connected;
        boolean enabled;
        boolean activityIn;
        boolean activityOut;
        int level;
        IconGroup iconGroup;
        int inetCondition;
        int rssi; // Only for logging.

        // Not used for comparison, just used for logging.
        long time;

        public void copyFrom(State state) {
            connected = state.connected;
            enabled = state.enabled;
            level = state.level;
            iconGroup = state.iconGroup;
            inetCondition = state.inetCondition;
            activityIn = state.activityIn;
            activityOut = state.activityOut;
            rssi = state.rssi;
            time = state.time;
        }

        @Override
        public String toString() {
            if (time != 0) {
                StringBuilder builder = new StringBuilder();
                toString(builder);
                return builder.toString();
            } else {
                return "Empty " + getClass().getSimpleName();
            }
        }

        protected void toString(StringBuilder builder) {
            builder.append("connected=").append(connected).append(',')
                    .append("enabled=").append(enabled).append(',')
                    .append("level=").append(level).append(',')
                    .append("inetCondition=").append(inetCondition).append(',')
                    .append("iconGroup=").append(iconGroup).append(',')
                    .append("activityIn=").append(activityIn).append(',')
                    .append("activityOut=").append(activityOut).append(',')
                    .append("rssi=").append(rssi).append(',')
                    .append("lastModified=").append(DateFormat.format("MM-dd HH:mm:ss", time));
        }

        @Override
        public boolean equals(Object o) {
            if (!o.getClass().equals(getClass())) {
                return false;
            }
            State other = (State) o;
            return other.connected == connected
                    && other.enabled == enabled
                    && other.level == level
                    && other.inetCondition == inetCondition
                    && other.iconGroup == iconGroup
                    && other.activityIn == activityIn
                    && other.activityOut == activityOut
                    && other.rssi == rssi;
        }
    }
}
