/*
 * Copyright (C) 2009 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 android.widget.cts;

import static com.android.compatibility.common.util.CtsMockitoUtils.within;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;

import android.app.Activity;
import android.app.Instrumentation;
import android.content.Context;
import android.media.AudioAttributes;
import android.media.AudioManager;
import android.media.AudioPlaybackConfiguration;
import android.media.MediaPlayer;
import android.os.SystemClock;
import android.util.Log;
import android.view.View.MeasureSpec;
import android.widget.MediaController;
import android.widget.VideoView;

import androidx.test.InstrumentationRegistry;
import androidx.test.annotation.UiThreadTest;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;

import com.android.compatibility.common.util.MediaUtils;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;

/**
 * Test {@link VideoView}.
 */
@LargeTest
@RunWith(AndroidJUnit4.class)
public class VideoViewTest {
    /** Debug TAG. **/
    private static final String TAG = "VideoViewTest";
    /** The maximum time to wait for an operation. */
    private static final long   TIME_OUT = 15000L;
    /** The interval time to wait for completing an operation. */
    private static final long   OPERATION_INTERVAL  = 1500L;
    /** The duration of R.raw.testvideo. */
    private static final int    TEST_VIDEO_DURATION = 11047;
    /** The full name of R.raw.testvideo. */
    private static final String VIDEO_NAME   = "testvideo.3gp";
    /** delta for duration in case user uses different decoders on different
        hardware that report a duration that's different by a few milliseconds */
    private static final int DURATION_DELTA = 100;
    /** AudioAttributes to be used by this player */
    private static final AudioAttributes AUDIO_ATTR = new AudioAttributes.Builder()
            .setUsage(AudioAttributes.USAGE_GAME)
            .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
            .build();

    private Instrumentation mInstrumentation;
    private Activity mActivity;
    private VideoView mVideoView;
    private String mVideoPath;

    @Rule
    public ActivityTestRule<VideoViewCtsActivity> mActivityRule =
            new ActivityTestRule<>(VideoViewCtsActivity.class);

    @Before
    public void setup() throws Throwable {
        mInstrumentation = InstrumentationRegistry.getInstrumentation();
        mActivity = mActivityRule.getActivity();
        mVideoView = (VideoView) mActivity.findViewById(R.id.videoview);

        mVideoPath = prepareSampleVideo();
        assertNotNull(mVideoPath);
    }

    private boolean hasCodec() {
        return MediaUtils.hasCodecsForResource(mActivity, R.raw.testvideo);
    }

    private String prepareSampleVideo() throws IOException {
        try (InputStream source = mActivity.getResources().openRawResource(R.raw.testvideo);
             OutputStream target = mActivity.openFileOutput(VIDEO_NAME, Context.MODE_PRIVATE)) {
            final byte[] buffer = new byte[1024];
            for (int len = source.read(buffer); len > 0; len = source.read(buffer)) {
                target.write(buffer, 0, len);
            }
        }

        return mActivity.getFileStreamPath(VIDEO_NAME).getAbsolutePath();
    }

    private void makeVideoView() throws Throwable {
        mActivityRule.runOnUiThread(() -> {
            MediaController mediaController = new MediaController(mActivity);
            mVideoView.setMediaController(mediaController);
        });
        mInstrumentation.waitForIdleSync();
    }

    @UiThreadTest
    @Test
    public void testConstructor() {
        new VideoView(mActivity);

        new VideoView(mActivity, null);

        new VideoView(mActivity, null, 0);
    }

    @Test
    public void testPlayVideo() throws Throwable {
        makeVideoView();
        // Don't run the test if the codec isn't supported.
        if (!hasCodec()) {
            Log.i(TAG, "SKIPPING testPlayVideo1(): codec is not supported");
            return;
        }

        final MediaPlayer.OnPreparedListener mockPreparedListener =
                mock(MediaPlayer.OnPreparedListener.class);
        mVideoView.setOnPreparedListener(mockPreparedListener);

        final MediaPlayer.OnCompletionListener mockCompletionListener =
                mock(MediaPlayer.OnCompletionListener.class);
        mVideoView.setOnCompletionListener(mockCompletionListener);

        mActivityRule.runOnUiThread(() -> mVideoView.setVideoPath(mVideoPath));
        verify(mockPreparedListener, within(TIME_OUT)).onPrepared(any(MediaPlayer.class));
        verify(mockPreparedListener, times(1)).onPrepared(any(MediaPlayer.class));
        verifyZeroInteractions(mockCompletionListener);

        mActivityRule.runOnUiThread(mVideoView::start);
        // wait time is longer than duration in case system is sluggish
        verify(mockCompletionListener, within(TIME_OUT)).onCompletion(any(MediaPlayer.class));
        verify(mockCompletionListener, times(1)).onCompletion(any(MediaPlayer.class));
    }

    private static final class MyPlaybackCallback extends AudioManager.AudioPlaybackCallback {
        boolean mMatchingPlayerFound = false;

        @Override
        public void onPlaybackConfigChanged(List<AudioPlaybackConfiguration> configs) {
            for (AudioPlaybackConfiguration apc : configs) {
                if (apc.getAudioAttributes().getUsage() == AUDIO_ATTR.getUsage()
                        && apc.getAudioAttributes().getContentType()
                                == AUDIO_ATTR.getContentType()) {
                    mMatchingPlayerFound = true;
                    break;
                }
            }
        }
    }

    @Test
    public void testAudioAttributes() throws Throwable {
        makeVideoView();
        // Don't run the test if the codec isn't supported.
        if (!hasCodec()) {
            Log.i(TAG, "SKIPPING testAudioAttributes(): codec is not supported");
            return;
        }

        final MediaPlayer.OnCompletionListener mockCompletionListener =
                mock(MediaPlayer.OnCompletionListener.class);
        mVideoView.setOnCompletionListener(mockCompletionListener);

        mVideoView.setAudioAttributes(AUDIO_ATTR);
        mVideoView.setAudioFocusRequest(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT);

        final AudioManager am = (AudioManager) mActivity.getSystemService(Context.AUDIO_SERVICE);
        final MyPlaybackCallback myCb = new MyPlaybackCallback();
        mActivityRule.runOnUiThread(() -> am.registerAudioPlaybackCallback(myCb, null));
        mActivityRule.runOnUiThread(() -> mVideoView.setVideoPath(mVideoPath));
        mActivityRule.runOnUiThread(mVideoView::start);
        // wait time is longer than duration in case system is sluggish
        verify(mockCompletionListener, within(TIME_OUT)).onCompletion(any(MediaPlayer.class));
        verify(mockCompletionListener, times(1)).onCompletion(any(MediaPlayer.class));

        // TODO is there a more compact way to test this with mockito?
        assertTrue("Audio playback configuration not found for VideoView",
                myCb.mMatchingPlayerFound);
    }

    @Test
    public void testSetOnErrorListener() throws Throwable {
        makeVideoView();

        final MediaPlayer.OnErrorListener mockErrorListener =
                mock(MediaPlayer.OnErrorListener.class);
        mVideoView.setOnErrorListener(mockErrorListener);

        mActivityRule.runOnUiThread(() -> {
            String path = "unknown path";
            mVideoView.setVideoPath(path);
            mVideoView.start();
        });
        mInstrumentation.waitForIdleSync();

        verify(mockErrorListener, within(TIME_OUT)).onError(
                any(MediaPlayer.class), anyInt(), anyInt());
        verify(mockErrorListener, times(1)).onError(any(MediaPlayer.class), anyInt(), anyInt());
    }

    @Test
    public void testGetBufferPercentage() throws Throwable {
        makeVideoView();
        // Don't run the test if the codec isn't supported.
        if (!hasCodec()) {
            Log.i(TAG, "SKIPPING testGetBufferPercentage(): codec is not supported");
            return;
        }

        final MediaPlayer.OnPreparedListener mockPreparedListener =
                mock(MediaPlayer.OnPreparedListener.class);
        mVideoView.setOnPreparedListener(mockPreparedListener);

        mActivityRule.runOnUiThread(() -> mVideoView.setVideoPath(mVideoPath));
        mInstrumentation.waitForIdleSync();

        verify(mockPreparedListener, within(TIME_OUT)).onPrepared(any(MediaPlayer.class));
        verify(mockPreparedListener, times(1)).onPrepared(any(MediaPlayer.class));
        int percent = mVideoView.getBufferPercentage();
        assertTrue(percent >= 0 && percent <= 100);
    }

    @UiThreadTest
    @Test
    public void testResolveAdjustedSize() {
        mVideoView = new VideoView(mActivity);

        final int desiredSize = 100;
        int resolvedSize = mVideoView.resolveAdjustedSize(desiredSize, MeasureSpec.UNSPECIFIED);
        assertEquals(desiredSize, resolvedSize);

        final int specSize = MeasureSpec.getSize(MeasureSpec.AT_MOST);
        resolvedSize = mVideoView.resolveAdjustedSize(desiredSize, MeasureSpec.AT_MOST);
        assertEquals(Math.min(desiredSize, specSize), resolvedSize);

        resolvedSize = mVideoView.resolveAdjustedSize(desiredSize, MeasureSpec.EXACTLY);
        assertEquals(specSize, resolvedSize);
    }

    @Test
    public void testGetDuration() throws Throwable {
        // Don't run the test if the codec isn't supported.
        if (!hasCodec()) {
            Log.i(TAG, "SKIPPING testGetDuration(): codec is not supported");
            return;
        }

        mActivityRule.runOnUiThread(() -> mVideoView.setVideoPath(mVideoPath));
        SystemClock.sleep(OPERATION_INTERVAL);
        assertTrue(Math.abs(mVideoView.getDuration() - TEST_VIDEO_DURATION) < DURATION_DELTA);
    }

    @UiThreadTest
    @Test
    public void testSetMediaController() {
        final MediaController ctlr = new MediaController(mActivity);
        mVideoView.setMediaController(ctlr);
    }
}
