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

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
import static org.mockito.Mockito.when;

import android.content.res.ColorStateList;
import android.graphics.Color;
import android.os.Handler;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.FrameLayout;

import androidx.test.filters.SmallTest;

import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardHostView;
import com.android.keyguard.KeyguardSecurityModel;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.DejankUtils;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.keyguard.DismissCallbackRegistry;
import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.statusbar.policy.KeyguardStateController;

import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnit;
import org.mockito.junit.MockitoRule;

@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
public class KeyguardBouncerTest extends SysuiTestCase {

    @Mock
    private FalsingManager mFalsingManager;
    @Mock
    private ViewMediatorCallback mViewMediatorCallback;
    @Mock
    private LockPatternUtils mLockPatternUtils;
    @Mock
    private DismissCallbackRegistry mDismissCallbackRegistry;
    @Mock
    private KeyguardHostView mKeyguardHostView;
    @Mock
    private ViewTreeObserver mViewTreeObserver;
    @Mock
    private KeyguardBouncer.BouncerExpansionCallback mExpansionCallback;
    @Mock
    private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
    @Mock
    private KeyguardStateController mKeyguardStateController;
    @Mock
    private KeyguardBypassController mKeyguardBypassController;
    @Mock
    private Handler mHandler;
    @Mock
    private KeyguardSecurityModel mKeyguardSecurityModel;
    @Rule
    public MockitoRule mRule = MockitoJUnit.rule();
    private ViewGroup mRootView;
    private KeyguardBouncer mBouncer;

    @Before
    public void setup() {
        allowTestableLooperAsMainThread();
        mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor);
        mDependency.injectTestDependency(KeyguardSecurityModel.class, mKeyguardSecurityModel);
        mDependency.injectMockDependency(KeyguardStateController.class);
        when(mKeyguardSecurityModel.getSecurityMode(anyInt()))
                .thenReturn(KeyguardSecurityModel.SecurityMode.None);
        DejankUtils.setImmediate(true);
        final ViewGroup container = new FrameLayout(getContext());
        when(mKeyguardHostView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
        when(mKeyguardHostView.getHeight()).thenReturn(500);
        mBouncer = new KeyguardBouncer(getContext(), mViewMediatorCallback,
                mLockPatternUtils, container, mDismissCallbackRegistry, mFalsingManager,
                mExpansionCallback, mKeyguardStateController, mKeyguardUpdateMonitor,
                mKeyguardBypassController, mHandler) {
            @Override
            protected void inflateView() {
                super.inflateView();
                mKeyguardView = mKeyguardHostView;
                mRoot = spy(mRoot);
                mRootView = mRoot;
            }
        };
    }

    @Test
    public void testInflateView_doesntCrash() {
        mBouncer.inflateView();
    }

    @Test
    public void testShow_notifiesFalsingManager() {
        mBouncer.show(true);
        verify(mFalsingManager).onBouncerShown();

        mBouncer.show(true, false);
        verifyNoMoreInteractions(mFalsingManager);
    }

    /**
     * Regression test: Invisible bouncer when occluded.
     */
    @Test
    public void testShow_bouncerIsVisible() {
        // Expand notification panel as if we were in the keyguard.
        mBouncer.ensureView();
        mBouncer.setExpansion(1);

        reset(mKeyguardHostView);
        when(mKeyguardHostView.getHeight()).thenReturn(500);

        mBouncer.show(true);
        verify(mKeyguardHostView).setAlpha(eq(1f));
        verify(mKeyguardHostView).setTranslationY(eq(0f));
    }

    @Test
    public void testShow_notifiesVisibility() {
        mBouncer.show(true);
        verify(mViewMediatorCallback).onBouncerVisiblityChanged(eq(true));
        verify(mExpansionCallback).onStartingToShow();

        // Not called again when visible
        reset(mViewMediatorCallback);
        mBouncer.show(true);
        verifyNoMoreInteractions(mViewMediatorCallback);
    }

    @Test
    public void testShow_triesToDismissKeyguard() {
        mBouncer.show(true);
        verify(mKeyguardHostView).dismiss(anyInt());
    }

    @Test
    public void testShow_resetsSecuritySelection() {
        mBouncer.show(false);
        verify(mKeyguardHostView, never()).showPrimarySecurityScreen();

        mBouncer.hide(false);
        mBouncer.show(true);
        verify(mKeyguardHostView).showPrimarySecurityScreen();
    }

    @Test
    public void testShow_animatesKeyguardView() {
        mBouncer.show(true);
        verify(mKeyguardHostView).startAppearAnimation();
    }

    @Test
    public void testShow_showsErrorMessage() {
        final String errorMessage = "an error message";
        when(mViewMediatorCallback.consumeCustomMessage()).thenReturn(errorMessage);
        mBouncer.show(true);
        verify(mKeyguardHostView).showErrorMessage(eq(errorMessage));
    }

    @Test
    public void testSetExpansion_notifiesFalsingManager() {
        mBouncer.ensureView();
        mBouncer.setExpansion(0.5f);

        mBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
        verify(mFalsingManager).onBouncerHidden();
        verify(mExpansionCallback).onFullyHidden();

        mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
        verify(mFalsingManager).onBouncerShown();
        verify(mExpansionCallback).onFullyShown();

        verify(mExpansionCallback, never()).onStartingToHide();
        mBouncer.setExpansion(0.9f);
        verify(mExpansionCallback).onStartingToHide();
    }

    @Test
    public void testSetExpansion_notifiesKeyguardView() {
        mBouncer.ensureView();
        mBouncer.setExpansion(0.1f);

        mBouncer.setExpansion(0);
        verify(mKeyguardHostView).onResume();
        verify(mRootView).announceForAccessibility(any());
    }

    @Test
    public void testHide_notifiesFalsingManager() {
        mBouncer.hide(false);
        verify(mFalsingManager).onBouncerHidden();
    }

    @Test
    public void testHide_notifiesVisibility() {
        mBouncer.hide(false);
        verify(mViewMediatorCallback).onBouncerVisiblityChanged(eq(false));
    }

    @Test
    public void testHide_notifiesDismissCallbackIfVisible() {
        mBouncer.hide(false);
        verifyZeroInteractions(mDismissCallbackRegistry);
        mBouncer.show(false);
        mBouncer.hide(false);
        verify(mDismissCallbackRegistry).notifyDismissCancelled();
    }

    @Test
    public void testHide_notShowingAnymore() {
        mBouncer.ensureView();
        mBouncer.show(false /* resetSecuritySelection */);
        mBouncer.hide(false /* destroyViews */);
        Assert.assertFalse("Not showing", mBouncer.isShowing());
    }

    @Test
    public void testShowPromptReason_propagates() {
        mBouncer.ensureView();
        mBouncer.showPromptReason(1);
        verify(mKeyguardHostView).showPromptReason(eq(1));
    }

    @Test
    public void testShowMessage_propagates() {
        final String message = "a message";
        mBouncer.ensureView();
        mBouncer.showMessage(message, ColorStateList.valueOf(Color.GREEN));
        verify(mKeyguardHostView).showMessage(eq(message), eq(ColorStateList.valueOf(Color.GREEN)));
    }

    @Test
    public void testShowOnDismissAction_showsBouncer() {
        final OnDismissAction dismissAction = () -> false;
        final Runnable cancelAction = () -> {};
        mBouncer.showWithDismissAction(dismissAction, cancelAction);
        verify(mKeyguardHostView).setOnDismissAction(dismissAction, cancelAction);
        Assert.assertTrue("Should be showing", mBouncer.isShowing());
    }

    @Test
    public void testStartPreHideAnimation_notifiesView() {
        final boolean[] ran = {false};
        final Runnable r = () -> ran[0] = true;
        mBouncer.startPreHideAnimation(r);
        Assert.assertTrue("Callback should have been invoked", ran[0]);

        ran[0] = false;
        mBouncer.ensureView();
        mBouncer.startPreHideAnimation(r);
        verify(mKeyguardHostView).startDisappearAnimation(r);
        Assert.assertFalse("Callback should have been deferred", ran[0]);
    }

    @Test
    public void testIsShowing_animated() {
        Assert.assertFalse("Show wasn't invoked yet", mBouncer.isShowing());
        mBouncer.show(true /* reset */);
        Assert.assertTrue("Should be showing", mBouncer.isShowing());
    }

    @Test
    public void testIsShowing_forSwipeUp() {
        mBouncer.setExpansion(1f);
        mBouncer.show(true /* reset */, false /* animated */);
        Assert.assertFalse("Should only be showing after collapsing notification panel",
                mBouncer.isShowing());
        mBouncer.setExpansion(0f);
        Assert.assertTrue("Should be showing", mBouncer.isShowing());
    }

    @Test
    public void testSetExpansion() {
        mBouncer.ensureView();
        mBouncer.setExpansion(0.5f);
        verify(mKeyguardHostView).setAlpha(anyFloat());
        verify(mKeyguardHostView).setTranslationY(anyFloat());
    }

    @Test
    public void testIsFullscreenBouncer_asksKeyguardView() {
        mBouncer.ensureView();
        mBouncer.isFullscreenBouncer();
        verify(mKeyguardHostView).getCurrentSecurityMode();
        verify(mKeyguardHostView, never()).getSecurityMode();
    }

    @Test
    public void testIsHiding_preHideOrHide() {
        Assert.assertFalse("Should not be hiding on initial state", mBouncer.isAnimatingAway());
        mBouncer.startPreHideAnimation(null /* runnable */);
        Assert.assertTrue("Should be hiding during pre-hide", mBouncer.isAnimatingAway());
        mBouncer.hide(false /* destroyView */);
        Assert.assertFalse("Should be hidden after hide()", mBouncer.isAnimatingAway());
    }

    @Test
    public void testIsHiding_skipsTranslation() {
        mBouncer.show(false /* reset */);
        reset(mKeyguardHostView);
        mBouncer.startPreHideAnimation(null /* runnable */);
        mBouncer.setExpansion(0.5f);
        verify(mKeyguardHostView, never()).setTranslationY(anyFloat());
        verify(mKeyguardHostView, never()).setAlpha(anyFloat());
    }

    @Test
    public void testIsSecure() {
        Assert.assertTrue("Bouncer is secure before inflating views", mBouncer.isSecure());

        mBouncer.ensureView();
        for (KeyguardSecurityModel.SecurityMode mode : KeyguardSecurityModel.SecurityMode.values()){
            reset(mKeyguardHostView);
            when(mKeyguardHostView.getSecurityMode()).thenReturn(mode);
            Assert.assertEquals("Security doesn't match for mode: " + mode,
                    mBouncer.isSecure(), mode != KeyguardSecurityModel.SecurityMode.None);
        }
    }

    @Test
    public void testIsShowingScrimmed_true() {
        doAnswer(invocation -> {
            assertThat(mBouncer.isScrimmed()).isTrue();
            return null;
        }).when(mExpansionCallback).onFullyShown();
        mBouncer.show(false /* resetSecuritySelection */, true /* animate */);
        assertThat(mBouncer.isScrimmed()).isTrue();
        mBouncer.hide(false /* destroyView */);
        assertThat(mBouncer.isScrimmed()).isFalse();
    }

    @Test
    public void testIsShowingScrimmed_false() {
        doAnswer(invocation -> {
            assertThat(mBouncer.isScrimmed()).isFalse();
            return null;
        }).when(mExpansionCallback).onFullyShown();
        mBouncer.show(false /* resetSecuritySelection */, false /* animate */);
        assertThat(mBouncer.isScrimmed()).isFalse();
    }

    @Test
    public void testWillDismissWithAction() {
        mBouncer.ensureView();
        Assert.assertFalse("Action not set yet", mBouncer.willDismissWithAction());
        when(mKeyguardHostView.hasDismissActions()).thenReturn(true);
        Assert.assertTrue("Action should exist", mBouncer.willDismissWithAction());
    }

    @Test
    public void testShow_delaysIfFaceAuthIsRunning() {
        when(mKeyguardStateController.isFaceAuthEnabled()).thenReturn(true);
        mBouncer.show(true /* reset */);

        ArgumentCaptor<Runnable> showRunnable = ArgumentCaptor.forClass(Runnable.class);
        verify(mHandler).postDelayed(showRunnable.capture(),
                eq(KeyguardBouncer.BOUNCER_FACE_DELAY));

        mBouncer.hide(false /* destroyView */);
        verify(mHandler).removeCallbacks(eq(showRunnable.getValue()));
    }

    @Test
    public void testShow_delaysIfFaceAuthIsRunning_unlessBypass() {
        when(mKeyguardStateController.isFaceAuthEnabled()).thenReturn(true);
        when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
        mBouncer.show(true /* reset */);

        verify(mHandler, never()).postDelayed(any(), anyLong());
    }

    @Test
    public void testRegisterUpdateMonitorCallback() {
        verify(mKeyguardUpdateMonitor).registerCallback(any());
    }

    @Test
    public void testInTransit_whenTranslation() {
        mBouncer.show(true);
        mBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
        assertThat(mBouncer.inTransit()).isFalse();
        mBouncer.setExpansion(0.5f);
        assertThat(mBouncer.inTransit()).isTrue();
        mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
        assertThat(mBouncer.inTransit()).isFalse();
    }
}
