/*
 * Copyright (C) 2019 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;

import static android.view.InsetsState.ITYPE_NAVIGATION_BAR;
import static android.view.InsetsState.ITYPE_STATUS_BAR;
import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS;

import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_TRANSITION_FROM_AOD;
import static com.android.internal.jank.InteractionJankMonitor.CUJ_LOCKSCREEN_TRANSITION_TO_AOD;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.os.SystemProperties;
import android.os.Trace;
import android.text.format.DateFormat;
import android.util.FloatProperty;
import android.util.Log;
import android.view.InsetsFlags;
import android.view.InsetsVisibilities;
import android.view.View;
import android.view.ViewDebug;
import android.view.WindowInsetsController.Appearance;
import android.view.WindowInsetsController.Behavior;
import android.view.animation.Interpolator;

import androidx.annotation.NonNull;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.DejankUtils;
import com.android.systemui.Dumpable;
import com.android.systemui.animation.Interpolators;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.policy.CallbackController;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Comparator;

import javax.inject.Inject;

/**
 * Tracks and reports on {@link StatusBarState}.
 */
@SysUISingleton
public class StatusBarStateControllerImpl implements
        SysuiStatusBarStateController,
        CallbackController<StateListener>,
        Dumpable {
    private static final String TAG = "SbStateController";
    private static final boolean DEBUG_IMMERSIVE_APPS =
            SystemProperties.getBoolean("persist.debug.immersive_apps", false);

    // Must be a power of 2
    private static final int HISTORY_SIZE = 32;

    private static final int MAX_STATE = StatusBarState.FULLSCREEN_USER_SWITCHER;
    private static final int MIN_STATE = StatusBarState.SHADE;

    private static final Comparator<RankedListener> sComparator =
            Comparator.comparingInt(o -> o.mRank);
    private static final FloatProperty<StatusBarStateControllerImpl> SET_DARK_AMOUNT_PROPERTY =
            new FloatProperty<StatusBarStateControllerImpl>("mDozeAmount") {

                @Override
                public void setValue(StatusBarStateControllerImpl object, float value) {
                    object.setDozeAmountInternal(value);
                }

                @Override
                public Float get(StatusBarStateControllerImpl object) {
                    return object.mDozeAmount;
                }
            };

    private final ArrayList<RankedListener> mListeners = new ArrayList<>();
    private final UiEventLogger mUiEventLogger;
    private int mState;
    private int mLastState;
    private int mUpcomingState;
    private boolean mLeaveOpenOnKeyguardHide;
    private boolean mKeyguardRequested;

    // Record the HISTORY_SIZE most recent states
    private int mHistoryIndex = 0;
    private HistoricalState[] mHistoricalRecords = new HistoricalState[HISTORY_SIZE];
    // This is used by InteractionJankMonitor to get callback from HWUI.
    private View mView;

    /**
     * If any of the system bars is hidden.
     */
    private boolean mIsFullscreen = false;

    /**
     * If the device is currently pulsing (AOD2).
     */
    private boolean mPulsing;

    /**
     * If the device is currently dozing or not.
     */
    private boolean mIsDozing;

    /**
     * If the status bar is currently expanded or not.
     */
    private boolean mIsExpanded;

    /**
     * Current {@link #mDozeAmount} animator.
     */
    private ValueAnimator mDarkAnimator;

    /**
     * Current doze amount in this frame.
     */
    private float mDozeAmount;

    /**
     * Where the animator will stop.
     */
    private float mDozeAmountTarget;

    /**
     * The type of interpolator that should be used to the doze animation.
     */
    private Interpolator mDozeInterpolator = Interpolators.FAST_OUT_SLOW_IN;

    @Inject
    public StatusBarStateControllerImpl(UiEventLogger uiEventLogger, DumpManager dumpManager) {
        mUiEventLogger = uiEventLogger;
        for (int i = 0; i < HISTORY_SIZE; i++) {
            mHistoricalRecords[i] = new HistoricalState();
        }

        dumpManager.registerDumpable(this);
    }

    @Override
    public int getState() {
        return mState;
    }

    @Override
    public boolean setState(int state, boolean force) {
        if (state > MAX_STATE || state < MIN_STATE) {
            throw new IllegalArgumentException("Invalid state " + state);
        }
        if (!force && state == mState) {
            return false;
        }

        // Record the to-be mState and mLastState
        recordHistoricalState(state /* newState */, mState /* lastState */, false);

        // b/139259891
        if (mState == StatusBarState.SHADE && state == StatusBarState.SHADE_LOCKED) {
            Log.e(TAG, "Invalid state transition: SHADE -> SHADE_LOCKED", new Throwable());
        }

        synchronized (mListeners) {
            String tag = getClass().getSimpleName() + "#setState(" + state + ")";
            DejankUtils.startDetectingBlockingIpcs(tag);
            for (RankedListener rl : new ArrayList<>(mListeners)) {
                rl.mListener.onStatePreChange(mState, state);
            }
            mLastState = mState;
            mState = state;
            mUpcomingState = state;
            mUiEventLogger.log(StatusBarStateEvent.fromState(mState));
            for (RankedListener rl : new ArrayList<>(mListeners)) {
                rl.mListener.onStateChanged(mState);
            }

            for (RankedListener rl : new ArrayList<>(mListeners)) {
                rl.mListener.onStatePostChange();
            }
            DejankUtils.stopDetectingBlockingIpcs(tag);
        }

        return true;
    }

    @Override
    public void setUpcomingState(int nextState) {
        mUpcomingState = nextState;
        recordHistoricalState(mUpcomingState /* newState */, mState /* lastState */, true);
    }

    @Override
    public int getCurrentOrUpcomingState() {
        return mUpcomingState;
    }

    @Override
    public boolean isDozing() {
        return mIsDozing;
    }

    @Override
    public boolean isPulsing() {
        return mPulsing;
    }

    @Override
    public float getDozeAmount() {
        return mDozeAmount;
    }

    @Override
    public boolean isExpanded() {
        return mIsExpanded;
    }

    @Override
    public boolean setPanelExpanded(boolean expanded) {
        if (mIsExpanded == expanded) {
            return false;
        }
        mIsExpanded = expanded;
        String tag = getClass().getSimpleName() + "#setIsExpanded";
        DejankUtils.startDetectingBlockingIpcs(tag);
        for (RankedListener rl : new ArrayList<>(mListeners)) {
            rl.mListener.onExpandedChanged(mIsExpanded);
        }
        DejankUtils.stopDetectingBlockingIpcs(tag);
        return true;
    }

    @Override
    public float getInterpolatedDozeAmount() {
        return mDozeInterpolator.getInterpolation(mDozeAmount);
    }

    @Override
    public boolean setIsDozing(boolean isDozing) {
        if (mIsDozing == isDozing) {
            return false;
        }

        mIsDozing = isDozing;

        synchronized (mListeners) {
            String tag = getClass().getSimpleName() + "#setIsDozing";
            DejankUtils.startDetectingBlockingIpcs(tag);
            for (RankedListener rl : new ArrayList<>(mListeners)) {
                rl.mListener.onDozingChanged(isDozing);
            }
            DejankUtils.stopDetectingBlockingIpcs(tag);
        }

        return true;
    }

    @Override
    public void setDozeAmount(float dozeAmount, boolean animated) {
        setAndInstrumentDozeAmount(null, dozeAmount, animated);
    }

    @Override
    public void setAndInstrumentDozeAmount(View view, float dozeAmount, boolean animated) {
        if (mDarkAnimator != null && mDarkAnimator.isRunning()) {
            if (animated && mDozeAmountTarget == dozeAmount) {
                return;
            } else {
                mDarkAnimator.cancel();
            }
        }

        // We don't need a new attached view if we already have one.
        if ((mView == null || !mView.isAttachedToWindow())
                && (view != null && view.isAttachedToWindow())) {
            mView = view;
        }
        mDozeAmountTarget = dozeAmount;
        if (animated) {
            startDozeAnimation();
        } else {
            setDozeAmountInternal(dozeAmount);
        }
    }

    private void startDozeAnimation() {
        if (mDozeAmount == 0f || mDozeAmount == 1f) {
            mDozeInterpolator = mIsDozing
                    ? Interpolators.FAST_OUT_SLOW_IN
                    : Interpolators.TOUCH_RESPONSE_REVERSE;
        }
        mDarkAnimator = ObjectAnimator.ofFloat(this, SET_DARK_AMOUNT_PROPERTY, mDozeAmountTarget);
        mDarkAnimator.setInterpolator(Interpolators.LINEAR);
        mDarkAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_WAKEUP);
        mDarkAnimator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationCancel(Animator animation) {
                cancelInteractionJankMonitor();
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                endInteractionJankMonitor();
            }

            @Override
            public void onAnimationStart(Animator animation) {
                beginInteractionJankMonitor();
            }
        });
        mDarkAnimator.start();
    }

    private void setDozeAmountInternal(float dozeAmount) {
        mDozeAmount = dozeAmount;
        float interpolatedAmount = mDozeInterpolator.getInterpolation(dozeAmount);
        synchronized (mListeners) {
            String tag = getClass().getSimpleName() + "#setDozeAmount";
            DejankUtils.startDetectingBlockingIpcs(tag);
            for (RankedListener rl : new ArrayList<>(mListeners)) {
                rl.mListener.onDozeAmountChanged(mDozeAmount, interpolatedAmount);
            }
            DejankUtils.stopDetectingBlockingIpcs(tag);
        }
    }

    private void beginInteractionJankMonitor() {
        if (mView != null && mView.isAttachedToWindow()) {
            InteractionJankMonitor.getInstance().begin(mView, getCujType());
        }
    }

    private void endInteractionJankMonitor() {
        InteractionJankMonitor.getInstance().end(getCujType());
    }

    private void cancelInteractionJankMonitor() {
        InteractionJankMonitor.getInstance().cancel(getCujType());
    }

    private int getCujType() {
        return mIsDozing ? CUJ_LOCKSCREEN_TRANSITION_TO_AOD : CUJ_LOCKSCREEN_TRANSITION_FROM_AOD;
    }

    @Override
    public boolean goingToFullShade() {
        return mState == StatusBarState.SHADE && mLeaveOpenOnKeyguardHide;
    }

    @Override
    public void setLeaveOpenOnKeyguardHide(boolean leaveOpen) {
        mLeaveOpenOnKeyguardHide = leaveOpen;
    }

    @Override
    public boolean leaveOpenOnKeyguardHide() {
        return mLeaveOpenOnKeyguardHide;
    }

    @Override
    public boolean fromShadeLocked() {
        return mLastState == StatusBarState.SHADE_LOCKED;
    }

    @Override
    public void addCallback(@NonNull StateListener listener) {
        synchronized (mListeners) {
            addListenerInternalLocked(listener, Integer.MAX_VALUE);
        }
    }

    /**
     * Add a listener and a rank based on the priority of this message
     * @param listener the listener
     * @param rank the order in which you'd like to be called. Ranked listeners will be
     * notified before unranked, and we will sort ranked listeners from low to high
     *
     * @deprecated This method exists only to solve latent inter-dependencies from refactoring
     * StatusBarState out of StatusBar.java. Any new listeners should be built not to need ranking
     * (i.e., they are non-dependent on the order of operations of StatusBarState listeners).
     */
    @Deprecated
    @Override
    public void addCallback(StateListener listener, @SbStateListenerRank int rank) {
        synchronized (mListeners) {
            addListenerInternalLocked(listener, rank);
        }
    }

    @GuardedBy("mListeners")
    private void addListenerInternalLocked(StateListener listener, int rank) {
        // Protect against double-subscribe
        for (RankedListener rl : mListeners) {
            if (rl.mListener.equals(listener)) {
                return;
            }
        }

        RankedListener rl = new SysuiStatusBarStateController.RankedListener(listener, rank);
        mListeners.add(rl);
        mListeners.sort(sComparator);
    }


    @Override
    public void removeCallback(@NonNull StateListener listener) {
        synchronized (mListeners) {
            mListeners.removeIf((it) -> it.mListener.equals(listener));
        }
    }

    @Override
    public void setKeyguardRequested(boolean keyguardRequested) {
        mKeyguardRequested = keyguardRequested;
    }

    @Override
    public boolean isKeyguardRequested() {
        return mKeyguardRequested;
    }

    @Override
    public void setSystemBarAttributes(@Appearance int appearance, @Behavior int behavior,
            InsetsVisibilities requestedVisibilities, String packageName) {
        boolean isFullscreen = !requestedVisibilities.getVisibility(ITYPE_STATUS_BAR)
                || !requestedVisibilities.getVisibility(ITYPE_NAVIGATION_BAR);
        if (mIsFullscreen != isFullscreen) {
            mIsFullscreen = isFullscreen;
            synchronized (mListeners) {
                for (RankedListener rl : new ArrayList<>(mListeners)) {
                    rl.mListener.onFullscreenStateChanged(isFullscreen);
                }
            }
        }

        // TODO (b/190543382): Finish the logging logic.
        // This section can be removed if we don't need to print it on logcat.
        if (DEBUG_IMMERSIVE_APPS) {
            boolean dim = (appearance & APPEARANCE_LOW_PROFILE_BARS) != 0;
            String behaviorName = ViewDebug.flagsToString(InsetsFlags.class, "behavior", behavior);
            String requestedVisibilityString = requestedVisibilities.toString();
            if (requestedVisibilityString.isEmpty()) {
                requestedVisibilityString = "none";
            }
            Log.d(TAG, packageName + " dim=" + dim + " behavior=" + behaviorName
                    + " requested visibilities: " + requestedVisibilityString);
        }
    }

    @Override
    public void setPulsing(boolean pulsing) {
        if (mPulsing != pulsing) {
            mPulsing = pulsing;
            synchronized (mListeners) {
                for (RankedListener rl : new ArrayList<>(mListeners)) {
                    rl.mListener.onPulsingChanged(pulsing);
                }
            }
        }
    }

    /**
     * Returns String readable state of status bar from {@link StatusBarState}
     */
    public static String describe(int state) {
        return StatusBarState.toShortString(state);
    }

    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.println("StatusBarStateController: ");
        pw.println(" mState=" + mState + " (" + describe(mState) + ")");
        pw.println(" mLastState=" + mLastState + " (" + describe(mLastState) + ")");
        pw.println(" mLeaveOpenOnKeyguardHide=" + mLeaveOpenOnKeyguardHide);
        pw.println(" mKeyguardRequested=" + mKeyguardRequested);
        pw.println(" mIsDozing=" + mIsDozing);
        pw.println(" Historical states:");
        // Ignore records without a timestamp
        int size = 0;
        for (int i = 0; i < HISTORY_SIZE; i++) {
            if (mHistoricalRecords[i].mTimestamp != 0) size++;
        }
        for (int i = mHistoryIndex + HISTORY_SIZE;
                i >= mHistoryIndex + HISTORY_SIZE - size + 1; i--) {
            pw.println("  (" + (mHistoryIndex + HISTORY_SIZE - i + 1) + ")"
                    + mHistoricalRecords[i & (HISTORY_SIZE - 1)]);
        }
    }

    private void recordHistoricalState(int newState, int lastState, boolean upcoming) {
        Trace.traceCounter(Trace.TRACE_TAG_APP, "statusBarState", newState);
        mHistoryIndex = (mHistoryIndex + 1) % HISTORY_SIZE;
        HistoricalState state = mHistoricalRecords[mHistoryIndex];
        state.mNewState = newState;
        state.mLastState = lastState;
        state.mTimestamp = System.currentTimeMillis();
        state.mUpcoming = upcoming;
    }

    /**
     * For keeping track of our previous state to help with debugging
     */
    private static class HistoricalState {
        int mNewState;
        int mLastState;
        long mTimestamp;
        boolean mUpcoming;

        @Override
        public String toString() {
            if (mTimestamp != 0) {
                StringBuilder sb = new StringBuilder();
                if (mUpcoming) {
                    sb.append("upcoming-");
                }
                sb.append("newState=").append(mNewState)
                        .append("(").append(describe(mNewState)).append(")");
                sb.append(" lastState=").append(mLastState).append("(").append(describe(mLastState))
                        .append(")");
                sb.append(" timestamp=")
                        .append(DateFormat.format("MM-dd HH:mm:ss", mTimestamp));

                return sb.toString();
            }
            return "Empty " + getClass().getSimpleName();
        }
    }
}
