/*
 * Copyright (C) 2017 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 junit.framework.Assert.assertTrue;

import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.os.Handler;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;

import androidx.test.filters.SmallTest;

import com.android.systemui.Dependency;
import com.android.systemui.InitController;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.bubbles.BubbleData;
import com.android.systemui.plugins.statusbar.NotificationSwipeActionHelper;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.VisualStabilityManager;
import com.android.systemui.statusbar.notification.collection.NotificationData;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.logging.NotificationLogger;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.NotificationGroupManager;
import com.android.systemui.statusbar.phone.ShadeController;
import com.android.systemui.util.Assert;

import com.google.android.collect.Lists;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.Spy;

import java.util.List;

@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class NotificationViewHierarchyManagerTest extends SysuiTestCase {
    @Mock private NotificationPresenter mPresenter;
    @Mock private NotificationData mNotificationData;
    @Spy private FakeListContainer mListContainer = new FakeListContainer();

    // Dependency mocks:
    @Mock private NotificationEntryManager mEntryManager;
    @Mock private NotificationLockscreenUserManager mLockscreenUserManager;
    @Mock private NotificationGroupManager mGroupManager;
    @Mock private VisualStabilityManager mVisualStabilityManager;
    @Mock private ShadeController mShadeController;

    private TestableLooper mTestableLooper;
    private Handler mHandler;
    private NotificationViewHierarchyManager mViewHierarchyManager;
    private NotificationTestHelper mHelper;
    private boolean mMadeReentrantCall = false;

    @Before
    public void setUp() {
        MockitoAnnotations.initMocks(this);
        mTestableLooper = TestableLooper.get(this);
        Assert.sMainLooper = mTestableLooper.getLooper();
        mHandler = Handler.createAsync(mTestableLooper.getLooper());

        mDependency.injectTestDependency(NotificationEntryManager.class, mEntryManager);
        mDependency.injectTestDependency(NotificationLockscreenUserManager.class,
                mLockscreenUserManager);
        mDependency.injectTestDependency(NotificationGroupManager.class, mGroupManager);
        mDependency.injectTestDependency(VisualStabilityManager.class, mVisualStabilityManager);
        mDependency.injectTestDependency(ShadeController.class, mShadeController);

        mHelper = new NotificationTestHelper(mContext);

        when(mEntryManager.getNotificationData()).thenReturn(mNotificationData);

        mViewHierarchyManager = new NotificationViewHierarchyManager(mContext,
                mHandler, mLockscreenUserManager, mGroupManager, mVisualStabilityManager,
                mock(StatusBarStateControllerImpl.class), mEntryManager,
                () -> mShadeController, new BubbleData(mContext),
                mock(KeyguardBypassController.class),
                mock(DynamicPrivacyController.class));
        Dependency.get(InitController.class).executePostInitTasks();
        mViewHierarchyManager.setUpWithPresenter(mPresenter, mListContainer);
    }

    private NotificationEntry createEntry() throws Exception {
        ExpandableNotificationRow row = mHelper.createRow();
        NotificationEntry entry = new NotificationEntry(row.getStatusBarNotification());
        entry.setRow(row);
        return entry;
    }

    @Test
    public void testNotificationsBecomingBundled() throws Exception {
        // Tests 3 top level notifications becoming a single bundled notification with |entry0| as
        // the summary.
        NotificationEntry entry0 = createEntry();
        NotificationEntry entry1 = createEntry();
        NotificationEntry entry2 = createEntry();

        // Set up the prior state to look like three top level notifications.
        mListContainer.addContainerView(entry0.getRow());
        mListContainer.addContainerView(entry1.getRow());
        mListContainer.addContainerView(entry2.getRow());
        when(mNotificationData.getActiveNotifications()).thenReturn(
                Lists.newArrayList(entry0, entry1, entry2));

        // Set up group manager to report that they should be bundled now.
        when(mGroupManager.isChildInGroupWithSummary(entry0.notification)).thenReturn(false);
        when(mGroupManager.isChildInGroupWithSummary(entry1.notification)).thenReturn(true);
        when(mGroupManager.isChildInGroupWithSummary(entry2.notification)).thenReturn(true);
        when(mGroupManager.getGroupSummary(entry1.notification)).thenReturn(entry0);
        when(mGroupManager.getGroupSummary(entry2.notification)).thenReturn(entry0);

        // Run updateNotifications - the view hierarchy should be reorganized.
        mViewHierarchyManager.updateNotificationViews();

        verify(mListContainer).notifyGroupChildAdded(entry1.getRow());
        verify(mListContainer).notifyGroupChildAdded(entry2.getRow());
        assertTrue(Lists.newArrayList(entry0.getRow()).equals(mListContainer.mRows));
    }

    @Test
    public void testNotificationsBecomingUnbundled() throws Exception {
        // Tests a bundled notification becoming three top level notifications.
        NotificationEntry entry0 = createEntry();
        NotificationEntry entry1 = createEntry();
        NotificationEntry entry2 = createEntry();
        entry0.getRow().addChildNotification(entry1.getRow());
        entry0.getRow().addChildNotification(entry2.getRow());

        // Set up the prior state to look like one top level notification.
        mListContainer.addContainerView(entry0.getRow());
        when(mNotificationData.getActiveNotifications()).thenReturn(
                Lists.newArrayList(entry0, entry1, entry2));

        // Set up group manager to report that they should not be bundled now.
        when(mGroupManager.isChildInGroupWithSummary(entry0.notification)).thenReturn(false);
        when(mGroupManager.isChildInGroupWithSummary(entry1.notification)).thenReturn(false);
        when(mGroupManager.isChildInGroupWithSummary(entry2.notification)).thenReturn(false);

        // Run updateNotifications - the view hierarchy should be reorganized.
        mViewHierarchyManager.updateNotificationViews();

        verify(mListContainer).notifyGroupChildRemoved(
                entry1.getRow(), entry0.getRow().getChildrenContainer());
        verify(mListContainer).notifyGroupChildRemoved(
                entry2.getRow(), entry0.getRow().getChildrenContainer());
        assertTrue(
                Lists.newArrayList(entry0.getRow(), entry1.getRow(), entry2.getRow())
                        .equals(mListContainer.mRows));
    }

    @Test
    public void testNotificationsBecomingSuppressed() throws Exception {
        // Tests two top level notifications becoming a suppressed summary and a child.
        NotificationEntry entry0 = createEntry();
        NotificationEntry entry1 = createEntry();
        entry0.getRow().addChildNotification(entry1.getRow());

        // Set up the prior state to look like a top level notification.
        mListContainer.addContainerView(entry0.getRow());
        when(mNotificationData.getActiveNotifications()).thenReturn(
                Lists.newArrayList(entry0, entry1));

        // Set up group manager to report a suppressed summary now.
        when(mGroupManager.isChildInGroupWithSummary(entry0.notification)).thenReturn(false);
        when(mGroupManager.isChildInGroupWithSummary(entry1.notification)).thenReturn(false);
        when(mGroupManager.isSummaryOfSuppressedGroup(entry0.notification)).thenReturn(true);

        // Run updateNotifications - the view hierarchy should be reorganized.
        mViewHierarchyManager.updateNotificationViews();

        verify(mListContainer).notifyGroupChildRemoved(
                entry1.getRow(), entry0.getRow().getChildrenContainer());
        assertTrue(Lists.newArrayList(entry0.getRow(), entry1.getRow()).equals(mListContainer.mRows));
        assertEquals(View.GONE, entry0.getRow().getVisibility());
        assertEquals(View.VISIBLE, entry1.getRow().getVisibility());
    }

    @Test
    public void testUpdateNotificationViews_appOps() throws Exception {
        NotificationEntry entry0 = createEntry();
        entry0.setRow(spy(entry0.getRow()));
        when(mNotificationData.getActiveNotifications()).thenReturn(
                Lists.newArrayList(entry0));
        mListContainer.addContainerView(entry0.getRow());

        mViewHierarchyManager.updateNotificationViews();

        verify(entry0.getRow(), times(1)).showAppOpsIcons(any());
    }

    @Test
    public void testReentrantCallsToOnDynamicPrivacyChangedPostForLater() {
        // GIVEN a ListContainer that will make a re-entrant call to updateNotificationViews()
        mMadeReentrantCall = false;
        doAnswer((invocation) -> {
            if (!mMadeReentrantCall) {
                mMadeReentrantCall = true;
                mViewHierarchyManager.onDynamicPrivacyChanged();
            }
            return null;
        }).when(mListContainer).setMaxDisplayedNotifications(anyInt());

        // WHEN we call updateNotificationViews()
        mViewHierarchyManager.updateNotificationViews();

        // THEN onNotificationViewUpdateFinished() is only called once
        verify(mListContainer).onNotificationViewUpdateFinished();

        // WHEN we drain the looper
        mTestableLooper.processAllMessages();

        // THEN updateNotificationViews() is called a second time (for the reentrant call)
        verify(mListContainer, times(2)).onNotificationViewUpdateFinished();
    }

    @Test
    public void testMultipleReentrantCallsToOnDynamicPrivacyChangedOnlyPostOnce() {
        // GIVEN a ListContainer that will make many re-entrant calls to updateNotificationViews()
        mMadeReentrantCall = false;
        doAnswer((invocation) -> {
            if (!mMadeReentrantCall) {
                mMadeReentrantCall = true;
                mViewHierarchyManager.onDynamicPrivacyChanged();
                mViewHierarchyManager.onDynamicPrivacyChanged();
                mViewHierarchyManager.onDynamicPrivacyChanged();
                mViewHierarchyManager.onDynamicPrivacyChanged();
            }
            return null;
        }).when(mListContainer).setMaxDisplayedNotifications(anyInt());

        // WHEN we call updateNotificationViews() and drain the looper
        mViewHierarchyManager.updateNotificationViews();
        verify(mListContainer).onNotificationViewUpdateFinished();
        clearInvocations(mListContainer);
        mTestableLooper.processAllMessages();

        // THEN updateNotificationViews() is called only one more time
        verify(mListContainer).onNotificationViewUpdateFinished();
    }

    private class FakeListContainer implements NotificationListContainer {
        final LinearLayout mLayout = new LinearLayout(mContext);
        final List<View> mRows = Lists.newArrayList();
        private boolean mMakeReentrantCallDuringSetMaxDisplayedNotifications;

        @Override
        public void setChildTransferInProgress(boolean childTransferInProgress) {}

        @Override
        public void changeViewPosition(ExpandableView child, int newIndex) {
            mRows.remove(child);
            mRows.add(newIndex, child);
        }

        @Override
        public void notifyGroupChildAdded(ExpandableView row) {}

        @Override
        public void notifyGroupChildRemoved(ExpandableView row, ViewGroup childrenContainer) {}

        @Override
        public void generateAddAnimation(ExpandableView child, boolean fromMoreCard) {}

        @Override
        public void generateChildOrderChangedEvent() {}

        @Override
        public void onReset(ExpandableView view) {}

        @Override
        public int getContainerChildCount() {
            return mRows.size();
        }

        @Override
        public View getContainerChildAt(int i) {
            return mRows.get(i);
        }

        @Override
        public void removeContainerView(View v) {
            mLayout.removeView(v);
            mRows.remove(v);
        }

        @Override
        public void addContainerView(View v) {
            mLayout.addView(v);
            mRows.add(v);
        }

        @Override
        public void setMaxDisplayedNotifications(int maxNotifications) {
            if (mMakeReentrantCallDuringSetMaxDisplayedNotifications) {
                mViewHierarchyManager.onDynamicPrivacyChanged();
            }
        }

        @Override
        public ViewGroup getViewParentForNotification(NotificationEntry entry) {
            return null;
        }

        @Override
        public void onHeightChanged(ExpandableView view, boolean animate) {}

        @Override
        public void resetExposedMenuView(boolean animate, boolean force) {}

        @Override
        public NotificationSwipeActionHelper getSwipeActionHelper() {
            return null;
        }

        @Override
        public void cleanUpViewStateForEntry(NotificationEntry entry) { }

        @Override
        public boolean isInVisibleLocation(NotificationEntry entry) {
            return true;
        }

        @Override
        public void setChildLocationsChangedListener(
                NotificationLogger.OnChildLocationsChangedListener listener) {}

        @Override
        public boolean hasPulsingNotifications() {
            return false;
        }

        @Override
        public void onNotificationViewUpdateFinished() { }
    }
}
