package com.android.systemui.statusbar

import android.test.suitebuilder.annotation.SmallTest
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
import com.android.systemui.ExpandHelper
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.classifier.FalsingCollector
import com.android.systemui.dump.DumpManager
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.media.MediaHierarchyManager
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.plugins.qs.QS
import com.android.systemui.shade.NotificationPanelViewController
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.NotificationTestHelper
import com.android.systemui.statusbar.notification.stack.AmbientState
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
import com.android.systemui.statusbar.phone.CentralSurfaces
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.phone.LSShadeTransitionLogger
import com.android.systemui.statusbar.phone.ScrimController
import com.android.systemui.statusbar.policy.FakeConfigurationController
import org.junit.After
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyFloat
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.ArgumentMatchers.anyLong
import org.mockito.ArgumentMatchers.eq
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.clearInvocations
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.Mockito.`when` as whenever
import org.mockito.junit.MockitoJUnit

private fun <T> anyObject(): T {
    return Mockito.anyObject<T>()
}

@SmallTest
@RunWithLooper(setAsMainLooper = true)
@RunWith(AndroidTestingRunner::class)
class LockscreenShadeTransitionControllerTest : SysuiTestCase() {

    lateinit var transitionController: LockscreenShadeTransitionController
    lateinit var row: ExpandableNotificationRow
    @Mock lateinit var statusbarStateController: SysuiStatusBarStateController
    @Mock lateinit var logger: LSShadeTransitionLogger
    @Mock lateinit var dumpManager: DumpManager
    @Mock lateinit var keyguardBypassController: KeyguardBypassController
    @Mock lateinit var lockScreenUserManager: NotificationLockscreenUserManager
    @Mock lateinit var falsingCollector: FalsingCollector
    @Mock lateinit var ambientState: AmbientState
    @Mock lateinit var wakefulnessLifecycle: WakefulnessLifecycle
    @Mock lateinit var mediaHierarchyManager: MediaHierarchyManager
    @Mock lateinit var scrimController: ScrimController
    @Mock lateinit var falsingManager: FalsingManager
    @Mock lateinit var notificationPanelController: NotificationPanelViewController
    @Mock lateinit var nsslController: NotificationStackScrollLayoutController
    @Mock lateinit var depthController: NotificationShadeDepthController
    @Mock lateinit var stackscroller: NotificationStackScrollLayout
    @Mock lateinit var expandHelperCallback: ExpandHelper.Callback
    @Mock lateinit var mCentralSurfaces: CentralSurfaces
    @Mock lateinit var qS: QS
    @Mock lateinit var singleShadeOverScroller: SingleShadeLockScreenOverScroller
    @Mock lateinit var splitShadeOverScroller: SplitShadeLockScreenOverScroller
    @JvmField @Rule val mockito = MockitoJUnit.rule()

    private val configurationController = FakeConfigurationController()

    @Before
    fun setup() {
        val helper = NotificationTestHelper(
                mContext,
                mDependency,
                TestableLooper.get(this))
        row = helper.createRow()
        context.getOrCreateTestableResources()
                .addOverride(R.bool.config_use_split_notification_shade, false)
        context.getOrCreateTestableResources()
            .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 100)
        transitionController =
            LockscreenShadeTransitionController(
                statusBarStateController = statusbarStateController,
                logger = logger,
                keyguardBypassController = keyguardBypassController,
                lockScreenUserManager = lockScreenUserManager,
                falsingCollector = falsingCollector,
                ambientState = ambientState,
                mediaHierarchyManager = mediaHierarchyManager,
                depthController = depthController,
                wakefulnessLifecycle = wakefulnessLifecycle,
                context = context,
                configurationController = configurationController,
                falsingManager = falsingManager,
                dumpManager = dumpManager,
                splitShadeOverScrollerFactory = { _, _ -> splitShadeOverScroller },
                singleShadeOverScrollerFactory = { singleShadeOverScroller },
                scrimTransitionController =
                LockscreenShadeScrimTransitionController(
                    scrimController, context, configurationController, dumpManager),
                keyguardTransitionControllerFactory = { notificationPanelController ->
                    LockscreenShadeKeyguardTransitionController(
                        mediaHierarchyManager,
                        notificationPanelController,
                        context,
                        configurationController,
                        dumpManager)
                })
        whenever(nsslController.view).thenReturn(stackscroller)
        whenever(nsslController.expandHelperCallback).thenReturn(expandHelperCallback)
        transitionController.notificationPanelController = notificationPanelController
        transitionController.centralSurfaces = mCentralSurfaces
        transitionController.qS = qS
        transitionController.setStackScroller(nsslController)
        whenever(statusbarStateController.state).thenReturn(StatusBarState.KEYGUARD)
        whenever(nsslController.isInLockedDownShade).thenReturn(false)
        whenever(qS.isFullyCollapsed).thenReturn(true)
        whenever(lockScreenUserManager.userAllowsPrivateNotificationsInPublic(anyInt())).thenReturn(
                true)
        whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(true)
        whenever(lockScreenUserManager.isLockscreenPublicMode(anyInt())).thenReturn(true)
        whenever(falsingCollector.shouldEnforceBouncer()).thenReturn(false)
        whenever(keyguardBypassController.bypassEnabled).thenReturn(false)
        clearInvocations(mCentralSurfaces)
    }

    @After
    fun tearDown() {
        transitionController.dragDownAnimator?.cancel()
    }

    @Test
    fun testCantDragDownWhenQSExpanded() {
        assertTrue("Can't drag down on keyguard", transitionController.canDragDown())
        whenever(qS.isFullyCollapsed).thenReturn(false)
        assertFalse("Can drag down when QS is expanded", transitionController.canDragDown())
    }

    @Test
    fun testCanDragDownInLockedDownShade() {
        whenever(statusbarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
        assertFalse("Can drag down in shade locked", transitionController.canDragDown())
        whenever(nsslController.isInLockedDownShade).thenReturn(true)
        assertTrue("Can't drag down in locked down shade", transitionController.canDragDown())
    }

    @Test
    fun testGoingToLockedShade() {
        transitionController.goToLockedShade(null)
        verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
    }

    @Test
    fun testWakingToShadeLockedWhenDozing() {
        whenever(statusbarStateController.isDozing).thenReturn(true)
        transitionController.goToLockedShade(null)
        verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
        assertTrue("Not waking to shade locked", transitionController.isWakingToShadeLocked)
    }

    @Test
    fun testNotWakingToShadeLockedWhenNotDozing() {
        whenever(statusbarStateController.isDozing).thenReturn(false)
        transitionController.goToLockedShade(null)
        verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
        assertFalse("Waking to shade locked when not dozing",
                transitionController.isWakingToShadeLocked)
    }

    @Test
    fun testGoToLockedShadeOnlyOnKeyguard() {
        whenever(statusbarStateController.state).thenReturn(StatusBarState.SHADE_LOCKED)
        transitionController.goToLockedShade(null)
        whenever(statusbarStateController.state).thenReturn(StatusBarState.SHADE)
        transitionController.goToLockedShade(null)
        verify(statusbarStateController, never()).setState(anyInt())
    }

    @Test
    fun testDontGoWhenShadeDisabled() {
        whenever(mCentralSurfaces.isShadeDisabled).thenReturn(true)
        transitionController.goToLockedShade(null)
        verify(statusbarStateController, never()).setState(anyInt())
    }

    @Test
    fun testUserExpandsViewOnGoingToFullShade() {
        assertFalse("Row shouldn't be user expanded yet", row.isUserExpanded)
        transitionController.goToLockedShade(row)
        assertTrue("Row wasn't user expanded on drag down", row.isUserExpanded)
    }

    @Test
    fun testTriggeringBouncerWhenPrivateNotificationsArentAllowed() {
        whenever(lockScreenUserManager.userAllowsPrivateNotificationsInPublic(anyInt())).thenReturn(
                false)
        transitionController.goToLockedShade(null)
        verify(statusbarStateController, never()).setState(anyInt())
        verify(statusbarStateController).setLeaveOpenOnKeyguardHide(true)
        verify(mCentralSurfaces).showBouncerWithDimissAndCancelIfKeyguard(anyObject(), anyObject())
    }

    @Test
    fun testTriggeringBouncerNoNotificationsOnLockscreen() {
        whenever(lockScreenUserManager.shouldShowLockscreenNotifications()).thenReturn(false)
        transitionController.goToLockedShade(null)
        verify(statusbarStateController, never()).setState(anyInt())
        verify(statusbarStateController).setLeaveOpenOnKeyguardHide(true)
        verify(mCentralSurfaces).showBouncerWithDimissAndCancelIfKeyguard(anyObject(), anyObject())
    }

    @Test
    fun testGoToLockedShadeCreatesQSAnimation() {
        transitionController.goToLockedShade(null)
        verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
        verify(notificationPanelController).animateToFullShade(anyLong())
        assertNotNull(transitionController.dragDownAnimator)
    }

    @Test
    fun testGoToLockedShadeDoesntCreateQSAnimation() {
        transitionController.goToLockedShade(null, needsQSAnimation = false)
        verify(statusbarStateController).setState(StatusBarState.SHADE_LOCKED)
        verify(notificationPanelController).animateToFullShade(anyLong())
        assertNull(transitionController.dragDownAnimator)
    }

    @Test
    fun testDragDownAmountDoesntCallOutInLockedDownShade() {
        whenever(nsslController.isInLockedDownShade).thenReturn(true)
        transitionController.dragDownAmount = 10f
        verify(nsslController, never()).setTransitionToFullShadeAmount(anyFloat())
        verify(mediaHierarchyManager, never()).setTransitionToFullShadeAmount(anyFloat())
        verify(scrimController, never()).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
        verify(notificationPanelController, never()).setTransitionToFullShadeAmount(anyFloat(),
                anyBoolean(), anyLong())
        verify(qS, never()).setTransitionToFullShadeAmount(anyFloat(), anyFloat())
    }

    @Test
    fun testDragDownAmountCallsOut() {
        transitionController.dragDownAmount = 10f
        verify(nsslController).setTransitionToFullShadeAmount(anyFloat())
        verify(mediaHierarchyManager).setTransitionToFullShadeAmount(anyFloat())
        verify(scrimController).setTransitionToFullShadeProgress(anyFloat(), anyFloat())
        verify(notificationPanelController).setTransitionToFullShadeAmount(anyFloat(),
                anyBoolean(), anyLong())
        verify(qS).setTransitionToFullShadeAmount(anyFloat(), anyFloat())
        verify(depthController).transitionToFullShadeProgress = anyFloat()
    }

    @Test
    fun testDragDownAmount_depthDistanceIsZero_setsProgressToZero() {
        context.getOrCreateTestableResources()
            .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 0)
        configurationController.notifyConfigurationChanged()

        transitionController.dragDownAmount = 10f

        verify(depthController).transitionToFullShadeProgress = 0f
    }

    @Test
    fun testDragDownAmount_depthDistanceNonZero_setsProgressBasedOnDistance() {
        context.getOrCreateTestableResources()
            .addOverride(R.dimen.lockscreen_shade_depth_controller_transition_distance, 100)
        configurationController.notifyConfigurationChanged()

        transitionController.dragDownAmount = 10f

        verify(depthController).transitionToFullShadeProgress = 0.1f
    }

    @Test
    fun setDragAmount_setsKeyguardTransitionProgress() {
        transitionController.dragDownAmount = 10f

        verify(notificationPanelController).setKeyguardTransitionProgress(anyFloat(), anyInt())
    }

    @Test
    fun setDragAmount_setsKeyguardAlphaBasedOnDistance() {
        val alphaDistance = context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance)
        transitionController.dragDownAmount = 10f

        val expectedAlpha = 1 - 10f / alphaDistance
        verify(notificationPanelController)
                .setKeyguardTransitionProgress(eq(expectedAlpha), anyInt())
    }

    @Test
    fun setDragAmount_notInSplitShade_setsKeyguardTranslationToZero() {
        val mediaTranslationY = 123
        disableSplitShade()
        whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(true)
        whenever(mediaHierarchyManager.getGuidedTransformationTranslationY())
            .thenReturn(mediaTranslationY)

        transitionController.dragDownAmount = 10f

        verify(notificationPanelController).setKeyguardTransitionProgress(anyFloat(), eq(0))
    }

    @Test
    fun setDragAmount_inSplitShade_setsKeyguardTranslationBasedOnMediaTranslation() {
        val mediaTranslationY = 123
        enableSplitShade()
        whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(true)
        whenever(mediaHierarchyManager.getGuidedTransformationTranslationY())
            .thenReturn(mediaTranslationY)

        transitionController.dragDownAmount = 10f

        verify(notificationPanelController)
            .setKeyguardTransitionProgress(anyFloat(), eq(mediaTranslationY))
    }

    @Test
    fun setDragAmount_inSplitShade_mediaNotShowing_setsKeyguardTranslationBasedOnDistance() {
        enableSplitShade()
        whenever(mediaHierarchyManager.isCurrentlyInGuidedTransformation()).thenReturn(false)
        whenever(mediaHierarchyManager.getGuidedTransformationTranslationY()).thenReturn(123)

        transitionController.dragDownAmount = 10f

        val distance =
            context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_keyguard_transition_distance)
        val offset =
            context.resources.getDimensionPixelSize(
                R.dimen.lockscreen_shade_keyguard_transition_vertical_offset)
        val expectedTranslation = 10f / distance * offset
        verify(notificationPanelController)
            .setKeyguardTransitionProgress(anyFloat(), eq(expectedTranslation.toInt()))
    }

    @Test
    fun setDragDownAmount_setsValueOnMediaHierarchyManager() {
        transitionController.dragDownAmount = 10f

        verify(mediaHierarchyManager).setTransitionToFullShadeAmount(10f)
    }

    @Test
    fun setDragAmount_setsScrimProgressBasedOnScrimDistance() {
        val distance = 10
        context.orCreateTestableResources
                .addOverride(R.dimen.lockscreen_shade_scrim_transition_distance, distance)
        configurationController.notifyConfigurationChanged()

        transitionController.dragDownAmount = 5f

        verify(scrimController).transitionToFullShadeProgress(
                progress = eq(0.5f),
                lockScreenNotificationsProgress = anyFloat()
        )
    }

    @Test
    fun setDragAmount_setsNotificationsScrimProgressBasedOnNotificationsScrimDistanceAndDelay() {
        val distance = 100
        val delay = 10
        context.orCreateTestableResources.addOverride(
                R.dimen.lockscreen_shade_notifications_scrim_transition_distance, distance)
        context.orCreateTestableResources.addOverride(
                R.dimen.lockscreen_shade_notifications_scrim_transition_delay, delay)
        configurationController.notifyConfigurationChanged()

        transitionController.dragDownAmount = 20f

        verify(scrimController).transitionToFullShadeProgress(
                progress = anyFloat(),
                lockScreenNotificationsProgress = eq(0.1f)
        )
    }

    @Test
    fun setDragAmount_dragAmountLessThanNotifDelayDistance_setsNotificationsScrimProgressToZero() {
        val distance = 100
        val delay = 50
        context.orCreateTestableResources.addOverride(
                R.dimen.lockscreen_shade_notifications_scrim_transition_distance, distance)
        context.orCreateTestableResources.addOverride(
                R.dimen.lockscreen_shade_notifications_scrim_transition_delay, delay)
        configurationController.notifyConfigurationChanged()

        transitionController.dragDownAmount = 20f

        verify(scrimController).transitionToFullShadeProgress(
                progress = anyFloat(),
                lockScreenNotificationsProgress = eq(0f)
        )
    }

    @Test
    fun setDragAmount_dragAmountMoreThanTotalDistance_setsNotificationsScrimProgressToOne() {
        val distance = 100
        val delay = 50
        context.orCreateTestableResources.addOverride(
                R.dimen.lockscreen_shade_notifications_scrim_transition_distance, distance)
        context.orCreateTestableResources.addOverride(
                R.dimen.lockscreen_shade_notifications_scrim_transition_delay, delay)
        configurationController.notifyConfigurationChanged()

        transitionController.dragDownAmount = 999999f

        verify(scrimController).transitionToFullShadeProgress(
                progress = anyFloat(),
                lockScreenNotificationsProgress = eq(1f)
        )
    }

    @Test
    fun setDragDownAmount_inSplitShade_setsValueOnMediaHierarchyManager() {
        enableSplitShade()

        transitionController.dragDownAmount = 10f

        verify(mediaHierarchyManager).setTransitionToFullShadeAmount(10f)
    }

    @Test
    fun setDragAmount_notInSplitShade_forwardsToSingleShadeOverScroller() {
        disableSplitShade()

        transitionController.dragDownAmount = 10f

        verify(singleShadeOverScroller).expansionDragDownAmount = 10f
        verifyZeroInteractions(splitShadeOverScroller)
    }

    @Test
    fun setDragAmount_inSplitShade_forwardsToSplitShadeOverScroller() {
        enableSplitShade()

        transitionController.dragDownAmount = 10f

        verify(splitShadeOverScroller).expansionDragDownAmount = 10f
        verifyZeroInteractions(singleShadeOverScroller)
    }

    @Test
    fun setDragDownAmount_inSplitShade_setsKeyguardStatusBarAlphaBasedOnDistance() {
        val alphaDistance = context.resources.getDimensionPixelSize(
            R.dimen.lockscreen_shade_npvc_keyguard_content_alpha_transition_distance)
        val dragDownAmount = 10f
        enableSplitShade()

        transitionController.dragDownAmount = dragDownAmount

        val expectedAlpha = 1 - dragDownAmount / alphaDistance
        verify(notificationPanelController).setKeyguardStatusBarAlpha(expectedAlpha)
    }

    @Test
    fun setDragDownAmount_notInSplitShade_setsKeyguardStatusBarAlphaToMinusOne() {
        disableSplitShade()

        transitionController.dragDownAmount = 10f

        verify(notificationPanelController).setKeyguardStatusBarAlpha(-1f)
    }

    private fun enableSplitShade() {
        setSplitShadeEnabled(true)
    }

    private fun disableSplitShade() {
        setSplitShadeEnabled(false)
    }

    private fun setSplitShadeEnabled(enabled: Boolean) {
        overrideResource(R.bool.config_use_split_notification_shade, enabled)
        configurationController.notifyConfigurationChanged()
    }

    /**
     * Wrapper around [ScrimController.transitionToFullShadeProgress] that has named parameters for
     * clarify and easier refactoring of parameter names.
     */
    private fun ScrimController.transitionToFullShadeProgress(
        progress: Float,
        lockScreenNotificationsProgress: Float
    ) {
        scrimController.setTransitionToFullShadeProgress(
                progress,
                lockScreenNotificationsProgress
        )
    }
}
