/*
 * Copyright (C) 2020 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.media

import android.media.MediaMetadata
import android.media.session.MediaController
import android.media.session.MediaSession
import android.media.session.PlaybackState
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.widget.SeekBar
import androidx.arch.core.executor.ArchTaskExecutor
import androidx.arch.core.executor.TaskExecutor
import androidx.test.filters.SmallTest

import com.android.systemui.SysuiTestCase
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.concurrency.FakeRepeatableExecutor
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat

import org.junit.After
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Mock
import org.mockito.Mockito.any
import org.mockito.Mockito.eq
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.`when` as whenever

@SmallTest
@RunWith(AndroidTestingRunner::class)
@TestableLooper.RunWithLooper
public class SeekBarViewModelTest : SysuiTestCase() {

    private lateinit var viewModel: SeekBarViewModel
    private lateinit var fakeExecutor: FakeExecutor
    private val taskExecutor: TaskExecutor = object : TaskExecutor() {
        override fun executeOnDiskIO(runnable: Runnable) {
            runnable.run()
        }
        override fun postToMainThread(runnable: Runnable) {
            runnable.run()
        }
        override fun isMainThread(): Boolean {
            return true
        }
    }
    @Mock private lateinit var mockController: MediaController
    @Mock private lateinit var mockTransport: MediaController.TransportControls
    private val token1 = MediaSession.Token(1, null)
    private val token2 = MediaSession.Token(2, null)

    @Before
    fun setUp() {
        fakeExecutor = FakeExecutor(FakeSystemClock())
        viewModel = SeekBarViewModel(FakeRepeatableExecutor(fakeExecutor))
        mockController = mock(MediaController::class.java)
        whenever(mockController.sessionToken).thenReturn(token1)
        mockTransport = mock(MediaController.TransportControls::class.java)

        // LiveData to run synchronously
        ArchTaskExecutor.getInstance().setDelegate(taskExecutor)
    }

    @After
    fun tearDown() {
        ArchTaskExecutor.getInstance().setDelegate(null)
    }

    @Test
    fun updateRegistersCallback() {
        viewModel.updateController(mockController)
        verify(mockController).registerCallback(any())
    }

    @Test
    fun updateSecondTimeDoesNotRepeatRegistration() {
        viewModel.updateController(mockController)
        viewModel.updateController(mockController)
        verify(mockController, times(1)).registerCallback(any())
    }

    @Test
    fun updateDifferentControllerUnregistersCallback() {
        viewModel.updateController(mockController)
        viewModel.updateController(mock(MediaController::class.java))
        verify(mockController).unregisterCallback(any())
    }

    @Test
    fun updateDifferentControllerRegistersCallback() {
        viewModel.updateController(mockController)
        val controller2 = mock(MediaController::class.java)
        whenever(controller2.sessionToken).thenReturn(token2)
        viewModel.updateController(controller2)
        verify(controller2).registerCallback(any())
    }

    @Test
    fun updateToNullUnregistersCallback() {
        viewModel.updateController(mockController)
        viewModel.updateController(null)
        verify(mockController).unregisterCallback(any())
    }

    @Test
    fun updateDurationWithPlayback() {
        // GIVEN that the duration is contained within the metadata
        val duration = 12000L
        val metadata = MediaMetadata.Builder().run {
            putLong(MediaMetadata.METADATA_KEY_DURATION, duration)
            build()
        }
        whenever(mockController.getMetadata()).thenReturn(metadata)
        // AND a valid playback state (ie. media session is not destroyed)
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // WHEN the controller is updated
        viewModel.updateController(mockController)
        // THEN the duration is extracted
        assertThat(viewModel.progress.value!!.duration).isEqualTo(duration)
        assertThat(viewModel.progress.value!!.enabled).isTrue()
    }

    @Test
    fun updateDurationWithoutPlayback() {
        // GIVEN that the duration is contained within the metadata
        val duration = 12000L
        val metadata = MediaMetadata.Builder().run {
            putLong(MediaMetadata.METADATA_KEY_DURATION, duration)
            build()
        }
        whenever(mockController.getMetadata()).thenReturn(metadata)
        // WHEN the controller is updated
        viewModel.updateController(mockController)
        // THEN the duration is extracted
        assertThat(viewModel.progress.value!!.duration).isEqualTo(duration)
        assertThat(viewModel.progress.value!!.enabled).isFalse()
    }

    @Test
    fun updateDurationNegative() {
        // GIVEN that the duration is negative
        val duration = -1L
        val metadata = MediaMetadata.Builder().run {
            putLong(MediaMetadata.METADATA_KEY_DURATION, duration)
            build()
        }
        whenever(mockController.getMetadata()).thenReturn(metadata)
        // AND a valid playback state (ie. media session is not destroyed)
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // WHEN the controller is updated
        viewModel.updateController(mockController)
        // THEN the seek bar is disabled
        assertThat(viewModel.progress.value!!.enabled).isFalse()
    }

    @Test
    fun updateDurationZero() {
        // GIVEN that the duration is zero
        val duration = 0L
        val metadata = MediaMetadata.Builder().run {
            putLong(MediaMetadata.METADATA_KEY_DURATION, duration)
            build()
        }
        whenever(mockController.getMetadata()).thenReturn(metadata)
        // AND a valid playback state (ie. media session is not destroyed)
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // WHEN the controller is updated
        viewModel.updateController(mockController)
        // THEN the seek bar is disabled
        assertThat(viewModel.progress.value!!.enabled).isFalse()
    }

    @Test
    fun updateDurationNoMetadata() {
        // GIVEN that the metadata is null
        whenever(mockController.getMetadata()).thenReturn(null)
        // AND a valid playback state (ie. media session is not destroyed)
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // WHEN the controller is updated
        viewModel.updateController(mockController)
        // THEN the seek bar is disabled
        assertThat(viewModel.progress.value!!.enabled).isFalse()
    }

    @Test
    fun updateElapsedTime() {
        // GIVEN that the PlaybackState contains the current position
        val position = 200L
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, position, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // WHEN the controller is updated
        viewModel.updateController(mockController)
        // THEN elapsed time is captured
        assertThat(viewModel.progress.value!!.elapsedTime).isEqualTo(200.toInt())
    }

    @Test
    fun updateSeekAvailable() {
        // GIVEN that seek is included in actions
        val state = PlaybackState.Builder().run {
            setActions(PlaybackState.ACTION_SEEK_TO)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // WHEN the controller is updated
        viewModel.updateController(mockController)
        // THEN seek is available
        assertThat(viewModel.progress.value!!.seekAvailable).isTrue()
    }

    @Test
    fun updateSeekNotAvailable() {
        // GIVEN that seek is not included in actions
        val state = PlaybackState.Builder().run {
            setActions(PlaybackState.ACTION_PLAY)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // WHEN the controller is updated
        viewModel.updateController(mockController)
        // THEN seek is not available
        assertThat(viewModel.progress.value!!.seekAvailable).isFalse()
    }

    @Test
    fun onSeek() {
        whenever(mockController.getTransportControls()).thenReturn(mockTransport)
        viewModel.updateController(mockController)
        // WHEN user input is dispatched
        val pos = 42L
        viewModel.onSeek(pos)
        fakeExecutor.runAllReady()
        // THEN transport controls should be used
        verify(mockTransport).seekTo(pos)
    }

    @Test
    fun onSeekWithFalse() {
        whenever(mockController.getTransportControls()).thenReturn(mockTransport)
        viewModel.updateController(mockController)
        // WHEN a false is received during the seek gesture
        val pos = 42L
        with(viewModel) {
            onSeekStarting()
            onSeekFalse()
            onSeek(pos)
        }
        fakeExecutor.runAllReady()
        // THEN the seek is rejected and the transport never receives seekTo
        verify(mockTransport, never()).seekTo(pos)
    }

    @Test
    fun onSeekProgress() {
        val pos = 42L
        with(viewModel) {
            onSeekStarting()
            onSeekProgress(pos)
        }
        fakeExecutor.runAllReady()
        // THEN then elapsed time should be updated
        assertThat(viewModel.progress.value!!.elapsedTime).isEqualTo(pos)
    }

    @Test
    fun onSeekProgressWithSeekStarting() {
        val pos = 42L
        with(viewModel) {
            onSeekProgress(pos)
        }
        fakeExecutor.runAllReady()
        // THEN then elapsed time should not be updated
        assertThat(viewModel.progress.value!!.elapsedTime).isNull()
    }

    @Test
    fun onProgressChangedFromUser() {
        // WHEN user starts dragging the seek bar
        val pos = 42
        val bar = SeekBar(context)
        with(viewModel.seekBarListener) {
            onStartTrackingTouch(bar)
            onProgressChanged(bar, pos, true)
        }
        fakeExecutor.runAllReady()
        // THEN then elapsed time should be updated
        assertThat(viewModel.progress.value!!.elapsedTime).isEqualTo(pos)
    }

    @Test
    fun onProgressChangedFromUserWithoutStartTrackingTouch() {
        // WHEN user starts dragging the seek bar
        val pos = 42
        val bar = SeekBar(context)
        with(viewModel.seekBarListener) {
            onProgressChanged(bar, pos, true)
        }
        fakeExecutor.runAllReady()
        // THEN then elapsed time should not be updated
        assertThat(viewModel.progress.value!!.elapsedTime).isNull()
    }

    @Test
    fun onProgressChangedNotFromUser() {
        whenever(mockController.getTransportControls()).thenReturn(mockTransport)
        viewModel.updateController(mockController)
        // WHEN user starts dragging the seek bar
        val pos = 42
        viewModel.seekBarListener.onProgressChanged(SeekBar(context), pos, false)
        fakeExecutor.runAllReady()
        // THEN transport controls should be used
        verify(mockTransport, never()).seekTo(pos.toLong())
    }

    @Test
    fun onStartTrackingTouch() {
        whenever(mockController.getTransportControls()).thenReturn(mockTransport)
        viewModel.updateController(mockController)
        // WHEN user starts dragging the seek bar
        val pos = 42
        val bar = SeekBar(context).apply {
            progress = pos
        }
        viewModel.seekBarListener.onStartTrackingTouch(bar)
        fakeExecutor.runAllReady()
        // THEN transport controls should be used
        verify(mockTransport, never()).seekTo(pos.toLong())
    }

    @Test
    fun onStopTrackingTouch() {
        whenever(mockController.getTransportControls()).thenReturn(mockTransport)
        viewModel.updateController(mockController)
        // WHEN user ends drag
        val pos = 42
        val bar = SeekBar(context).apply {
            progress = pos
        }
        viewModel.seekBarListener.onStopTrackingTouch(bar)
        fakeExecutor.runAllReady()
        // THEN transport controls should be used
        verify(mockTransport).seekTo(pos.toLong())
    }

    @Test
    fun onStopTrackingTouchAfterProgress() {
        whenever(mockController.getTransportControls()).thenReturn(mockTransport)
        viewModel.updateController(mockController)
        // WHEN user starts dragging the seek bar
        val pos = 42
        val progPos = 84
        val bar = SeekBar(context).apply {
            progress = pos
        }
        with(viewModel.seekBarListener) {
            onStartTrackingTouch(bar)
            onProgressChanged(bar, progPos, true)
            onStopTrackingTouch(bar)
        }
        fakeExecutor.runAllReady()
        // THEN then elapsed time should be updated
        verify(mockTransport).seekTo(eq(pos.toLong()))
    }

    @Test
    fun queuePollTaskWhenPlaying() {
        // GIVEN that the track is playing
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 100L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // WHEN the controller is updated
        viewModel.updateController(mockController)
        // THEN a task is queued
        assertThat(fakeExecutor.numPending()).isEqualTo(1)
    }

    @Test
    fun noQueuePollTaskWhenStopped() {
        // GIVEN that the playback state is stopped
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_STOPPED, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // WHEN updated
        viewModel.updateController(mockController)
        // THEN an update task is not queued
        assertThat(fakeExecutor.numPending()).isEqualTo(0)
    }

    @Test
    fun queuePollTaskWhenListening() {
        // GIVEN listening
        viewModel.listening = true
        with(fakeExecutor) {
            advanceClockToNext()
            runAllReady()
        }
        // AND the playback state is playing
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // WHEN updated
        viewModel.updateController(mockController)
        // THEN an update task is queued
        assertThat(fakeExecutor.numPending()).isEqualTo(1)
    }

    @Test
    fun noQueuePollTaskWhenNotListening() {
        // GIVEN not listening
        viewModel.listening = false
        with(fakeExecutor) {
            advanceClockToNext()
            runAllReady()
        }
        // AND the playback state is playing
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // WHEN updated
        viewModel.updateController(mockController)
        // THEN an update task is not queued
        assertThat(fakeExecutor.numPending()).isEqualTo(0)
    }

    @Test
    fun pollTaskQueuesAnotherPollTaskWhenPlaying() {
        // GIVEN that the track is playing
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 100L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        viewModel.updateController(mockController)
        // WHEN the next task runs
        with(fakeExecutor) {
            advanceClockToNext()
            runAllReady()
        }
        // THEN another task is queued
        assertThat(fakeExecutor.numPending()).isEqualTo(1)
    }

    @Test
    fun noQueuePollTaskWhenSeeking() {
        // GIVEN listening
        viewModel.listening = true
        // AND the playback state is playing
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        viewModel.updateController(mockController)
        with(fakeExecutor) {
            advanceClockToNext()
            runAllReady()
        }
        // WHEN seek starts
        viewModel.onSeekStarting()
        with(fakeExecutor) {
            advanceClockToNext()
            runAllReady()
        }
        // THEN an update task is not queued because we don't want it fighting with the user when
        // they are trying to move the thumb.
        assertThat(fakeExecutor.numPending()).isEqualTo(0)
    }

    @Test
    fun queuePollTaskWhenDoneSeekingWithFalse() {
        // GIVEN listening
        viewModel.listening = true
        // AND the playback state is playing
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        viewModel.updateController(mockController)
        with(fakeExecutor) {
            advanceClockToNext()
            runAllReady()
        }
        // WHEN seek finishes after a false
        with(viewModel) {
            onSeekStarting()
            onSeekFalse()
            onSeek(42L)
        }
        with(fakeExecutor) {
            advanceClockToNext()
            runAllReady()
        }
        // THEN an update task is queued because the gesture was ignored and progress was restored.
        assertThat(fakeExecutor.numPending()).isEqualTo(1)
    }

    @Test
    fun noQueuePollTaskWhenDoneSeeking() {
        // GIVEN listening
        viewModel.listening = true
        // AND the playback state is playing
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        viewModel.updateController(mockController)
        with(fakeExecutor) {
            advanceClockToNext()
            runAllReady()
        }
        // WHEN seek finishes after a false
        with(viewModel) {
            onSeekStarting()
            onSeek(42L)
        }
        with(fakeExecutor) {
            advanceClockToNext()
            runAllReady()
        }
        // THEN no update task is queued because we are waiting for an updated playback state to be
        // returned in response to the seek.
        assertThat(fakeExecutor.numPending()).isEqualTo(0)
    }

    @Test
    fun startListeningQueuesPollTask() {
        // GIVEN not listening
        viewModel.listening = false
        with(fakeExecutor) {
            advanceClockToNext()
            runAllReady()
        }
        // AND the playback state is playing
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_STOPPED, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        viewModel.updateController(mockController)
        // WHEN start listening
        viewModel.listening = true
        // THEN an update task is queued
        assertThat(fakeExecutor.numPending()).isEqualTo(1)
    }

    @Test
    fun playbackChangeQueuesPollTask() {
        viewModel.updateController(mockController)
        val captor = ArgumentCaptor.forClass(MediaController.Callback::class.java)
        verify(mockController).registerCallback(captor.capture())
        val callback = captor.value
        // WHEN the callback receives an new state
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 100L, 1f)
            build()
        }
        callback.onPlaybackStateChanged(state)
        with(fakeExecutor) {
            advanceClockToNext()
            runAllReady()
        }
        // THEN an update task is queued
        assertThat(fakeExecutor.numPending()).isEqualTo(1)
    }

    @Test
    fun clearSeekBar() {
        // GIVEN that the duration is contained within the metadata
        val metadata = MediaMetadata.Builder().run {
            putLong(MediaMetadata.METADATA_KEY_DURATION, 12000L)
            build()
        }
        whenever(mockController.getMetadata()).thenReturn(metadata)
        // AND a valid playback state (ie. media session is not destroyed)
        val state = PlaybackState.Builder().run {
            setState(PlaybackState.STATE_PLAYING, 200L, 1f)
            build()
        }
        whenever(mockController.getPlaybackState()).thenReturn(state)
        // AND the controller has been updated
        viewModel.updateController(mockController)
        // WHEN the controller is cleared on the event when the session is destroyed
        viewModel.clearController()
        with(fakeExecutor) {
            advanceClockToNext()
            runAllReady()
        }
        // THEN the seek bar is disabled
        assertThat(viewModel.progress.value!!.enabled).isFalse()
    }

    @Test
    fun clearSeekBarUnregistersCallback() {
        viewModel.updateController(mockController)
        viewModel.clearController()
        fakeExecutor.runAllReady()
        verify(mockController).unregisterCallback(any())
    }

    @Test
    fun destroyUnregistersCallback() {
        viewModel.updateController(mockController)
        viewModel.onDestroy()
        fakeExecutor.runAllReady()
        verify(mockController).unregisterCallback(any())
    }
}
