/*
 * Copyright (C) 2016 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.notification;

import android.os.Handler;
import android.os.SystemClock;
import android.view.View;

import androidx.collection.ArraySet;

import com.android.systemui.Dumpable;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener;

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

/**
 * A manager that ensures that notifications are visually stable. It will suppress reorderings
 * and reorder at the right time when they are out of view.
 */
public class VisualStabilityManager implements OnHeadsUpChangedListener, Dumpable {

    private static final long TEMPORARY_REORDERING_ALLOWED_DURATION = 1000;

    private final ArrayList<Callback> mReorderingAllowedCallbacks = new ArrayList<>();
    private final ArraySet<Callback> mPersistentReorderingCallbacks = new ArraySet<>();
    private final ArrayList<Callback> mGroupChangesAllowedCallbacks = new ArrayList<>();
    private final ArraySet<Callback> mPersistentGroupCallbacks = new ArraySet<>();
    private final Handler mHandler;

    private boolean mPanelExpanded;
    private boolean mScreenOn;
    private boolean mReorderingAllowed;
    private boolean mGroupChangedAllowed;
    private boolean mIsTemporaryReorderingAllowed;
    private long mTemporaryReorderingStart;
    private VisibilityLocationProvider mVisibilityLocationProvider;
    private ArraySet<View> mAllowedReorderViews = new ArraySet<>();
    private ArraySet<NotificationEntry> mLowPriorityReorderingViews = new ArraySet<>();
    private ArraySet<View> mAddedChildren = new ArraySet<>();
    private boolean mPulsing;

    /**
     * Injected constructor. See {@link NotificationsModule}.
     */
    public VisualStabilityManager(
            NotificationEntryManager notificationEntryManager,
            @Main Handler handler) {

        mHandler = handler;

        notificationEntryManager.addNotificationEntryListener(new NotificationEntryListener() {
            @Override
            public void onPreEntryUpdated(NotificationEntry entry) {
                final boolean ambientStateHasChanged =
                        entry.isAmbient() != entry.getRow().isLowPriority();
                if (ambientStateHasChanged) {
                    // note: entries are removed in onReorderingFinished
                    mLowPriorityReorderingViews.add(entry);
                }
            }
        });
    }

    public void setUpWithPresenter(NotificationPresenter presenter) {
    }

    /**
     * Add a callback to invoke when reordering is allowed again.
     *
     * @param callback the callback to add
     * @param persistent {@code true} if this callback should this callback be persisted, otherwise
     *                               it will be removed after a single invocation
     */
    public void addReorderingAllowedCallback(Callback callback, boolean persistent) {
        if (persistent) {
            mPersistentReorderingCallbacks.add(callback);
        }
        if (mReorderingAllowedCallbacks.contains(callback)) {
            return;
        }
        mReorderingAllowedCallbacks.add(callback);
    }

    /**
     * Add a callback to invoke when group changes are allowed again.
     *
     * @param callback the callback to add
     * @param persistent {@code true} if this callback should this callback be persisted, otherwise
     *                               it will be removed after a single invocation
     */
    public void addGroupChangesAllowedCallback(Callback callback, boolean persistent) {
        if (persistent) {
            mPersistentGroupCallbacks.add(callback);
        }
        if (mGroupChangesAllowedCallbacks.contains(callback)) {
            return;
        }
        mGroupChangesAllowedCallbacks.add(callback);
    }

    /**
     * Set the panel to be expanded.
     */
    public void setPanelExpanded(boolean expanded) {
        mPanelExpanded = expanded;
        updateAllowedStates();
    }

    /**
     * @param screenOn whether the screen is on
     */
    public void setScreenOn(boolean screenOn) {
        mScreenOn = screenOn;
        updateAllowedStates();
    }

    /**
     * @param pulsing whether we are currently pulsing for ambient display.
     */
    public void setPulsing(boolean pulsing) {
        if (mPulsing == pulsing) {
            return;
        }
        mPulsing = pulsing;
        updateAllowedStates();
    }

    private void updateAllowedStates() {
        boolean reorderingAllowed =
                (!mScreenOn || !mPanelExpanded || mIsTemporaryReorderingAllowed) && !mPulsing;
        boolean changedToTrue = reorderingAllowed && !mReorderingAllowed;
        mReorderingAllowed = reorderingAllowed;
        if (changedToTrue) {
            notifyChangeAllowed(mReorderingAllowedCallbacks, mPersistentReorderingCallbacks);
        }
        boolean groupChangesAllowed = (!mScreenOn || !mPanelExpanded) && !mPulsing;
        changedToTrue = groupChangesAllowed && !mGroupChangedAllowed;
        mGroupChangedAllowed = groupChangesAllowed;
        if (changedToTrue) {
            notifyChangeAllowed(mGroupChangesAllowedCallbacks, mPersistentGroupCallbacks);
        }
    }

    private void notifyChangeAllowed(ArrayList<Callback> callbacks,
            ArraySet<Callback> persistentCallbacks) {
        for (int i = 0; i < callbacks.size(); i++) {
            Callback callback = callbacks.get(i);
            callback.onChangeAllowed();
            if (!persistentCallbacks.contains(callback)) {
                callbacks.remove(callback);
                i--;
            }
        }
    }

    /**
     * @return whether reordering is currently allowed in general.
     */
    public boolean isReorderingAllowed() {
        return mReorderingAllowed;
    }

    /**
     * @return whether changes in the grouping should be allowed right now.
     */
    public boolean areGroupChangesAllowed() {
        return mGroupChangedAllowed;
    }

    /**
     * @return whether a specific notification is allowed to reorder. Certain notifications are
     * allowed to reorder even if {@link #isReorderingAllowed()} returns false, like newly added
     * notifications or heads-up notifications that are out of view.
     */
    public boolean canReorderNotification(ExpandableNotificationRow row) {
        if (mReorderingAllowed) {
            return true;
        }
        if (mAddedChildren.contains(row)) {
            return true;
        }
        if (mLowPriorityReorderingViews.contains(row.getEntry())) {
            return true;
        }
        if (mAllowedReorderViews.contains(row)
                && !mVisibilityLocationProvider.isInVisibleLocation(row.getEntry())) {
            return true;
        }
        return false;
    }

    public void setVisibilityLocationProvider(
            VisibilityLocationProvider visibilityLocationProvider) {
        mVisibilityLocationProvider = visibilityLocationProvider;
    }

    public void onReorderingFinished() {
        mAllowedReorderViews.clear();
        mAddedChildren.clear();
        mLowPriorityReorderingViews.clear();
    }

    @Override
    public void onHeadsUpStateChanged(NotificationEntry entry, boolean isHeadsUp) {
        if (isHeadsUp) {
            // Heads up notifications should in general be allowed to reorder if they are out of
            // view and stay at the current location if they aren't.
            mAllowedReorderViews.add(entry.getRow());
        }
    }

    /**
     * Temporarily allows reordering of the entire shade for a period of 1000ms. Subsequent calls
     * to this method will extend the timer.
     */
    public void temporarilyAllowReordering() {
        mHandler.removeCallbacks(mOnTemporaryReorderingExpired);
        mHandler.postDelayed(mOnTemporaryReorderingExpired, TEMPORARY_REORDERING_ALLOWED_DURATION);
        if (!mIsTemporaryReorderingAllowed) {
            mTemporaryReorderingStart = SystemClock.elapsedRealtime();
        }
        mIsTemporaryReorderingAllowed = true;
        updateAllowedStates();
    }

    private final Runnable mOnTemporaryReorderingExpired = () -> {
        mIsTemporaryReorderingAllowed = false;
        updateAllowedStates();
    };

    /**
     * Notify the visual stability manager that a new view was added and should be allowed to
     * reorder next time.
     */
    public void notifyViewAddition(View view) {
        mAddedChildren.add(view);
    }

    @Override
    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        pw.println("VisualStabilityManager state:");
        pw.print("  mIsTemporaryReorderingAllowed="); pw.println(mIsTemporaryReorderingAllowed);
        pw.print("  mTemporaryReorderingStart="); pw.println(mTemporaryReorderingStart);

        long now = SystemClock.elapsedRealtime();
        pw.print("    Temporary reordering window has been open for ");
        pw.print(now - (mIsTemporaryReorderingAllowed ? mTemporaryReorderingStart : now));
        pw.println("ms");

        pw.println();
    }

    public interface Callback {
        /**
         * Called when changing is allowed again.
         */
        void onChangeAllowed();
    }

}
