// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.content.browser.androidoverlay;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import android.app.Activity;
import android.app.Dialog;
import android.os.Binder;
import android.os.IBinder;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.WindowManager;

// TODO(liberato): prior to M, this was ...policy.impl.PhoneWindow
import com.android.internal.policy.PhoneWindow;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
import org.robolectric.Shadows;
import org.robolectric.annotation.Config;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.shadows.ShadowDialog;
import org.robolectric.shadows.ShadowPhoneWindow;
import org.robolectric.shadows.ShadowSurfaceView;

import org.chromium.base.test.BaseRobolectricTestRunner;
import org.chromium.gfx.mojom.Rect;
import org.chromium.media.mojom.AndroidOverlayConfig;

/**
 * Tests for DialogOverlayCore.
 */
@RunWith(BaseRobolectricTestRunner.class)
@Config(manifest = Config.NONE)
public class DialogOverlayCoreTest {
    private Activity mActivity;

    AndroidOverlayConfig mConfig = new AndroidOverlayConfig();

    // Should we request a panel?
    boolean mAsPanel;

    // DialogCore under test.
    DialogOverlayCore mCore;

    // The dialog that we've provided to |mCore|.
    Dialog mDialog;

    // Fake window token that we'll send to |mCore|.
    IBinder mWindowToken = new Binder();

    // Surface that will be provided by |mDialog|.
    Surface mSurface = new Surface();

    // SurfaceHolder that will be provided by |mDialog|.
    SurfaceHolder mHolder = new MyFakeSurfaceHolder(mSurface);

    /**
     * Robolectric shadow for PhoneWindow.  This one keeps track of takeSurface() calls.
     * TODO(liberato): the @Impl specifies 'minSdk=M' in the robolectric source.
     */
    @Implements(value = PhoneWindow.class, isInAndroidSdk = false)
    public static class MyPhoneWindowShadow extends ShadowPhoneWindow {
        public MyPhoneWindowShadow() {}

        private SurfaceHolder.Callback2 mCallback;
        private WindowManager.LayoutParams mLayoutParams;
        public boolean mDidUpdateParams;

        @Implementation
        public void takeSurface(SurfaceHolder.Callback2 callback) {
            mCallback = callback;
        }

        @Implementation
        public void setAttributes(WindowManager.LayoutParams layoutParams) {
            mLayoutParams = layoutParams;
            mDidUpdateParams = true;
        }
    }

    /**
     * The default fake surface holder doesn't let us provide a surface.
     */
    public static class MyFakeSurfaceHolder extends ShadowSurfaceView.FakeSurfaceHolder {
        private Surface mSurface;

        // @param surface The Surface that we'll provide via getSurface.
        public MyFakeSurfaceHolder(Surface surface) {
            mSurface = surface;
        }

        @Override
        public Surface getSurface() {
            return mSurface;
        }
    }

    @Before
    public void setUp() {
        mActivity = Robolectric.buildActivity(Activity.class).setup().get();

        mConfig = new AndroidOverlayConfig();
        mConfig.rect = new Rect();
        mConfig.rect.x = 0;
        mConfig.rect.y = 1;
        mConfig.rect.width = 2;
        mConfig.rect.height = 3;
    }

    public void createOverlay() {
        mCore = new DialogOverlayCore();
        mCore.initialize(mActivity, mConfig, mHost, mAsPanel);
        mDialog = mCore.getDialog();

        // Nothing should be called yet.
        checkOverlayDidntCall();

        // The dialog should not be shown yet.
        checkDialogIsNotShown();
    }

    // Make sure that the overlay didn't provide us with a surface, or notify us that it was
    // destroyed, or wait for cleanup.
    void checkOverlayDidntCall() {
        assertEquals(null, mHost.surface());
        assertEquals(0, mHost.destroyedCount());
        assertEquals(0, mHost.waitCloseCount());
        assertEquals(0, mHost.enforceCloseCount());
    }

    // Return the SurfaceHolder callback that was provided to takeSurface(), if any.
    SurfaceHolder.Callback2 holderCallback() {
        return ((MyPhoneWindowShadow) Shadows.shadowOf(mDialog.getWindow())).mCallback;
    }

    // Return the LayoutPararms that was most recently provided to the dialog.
    WindowManager.LayoutParams layoutParams() {
        return ((MyPhoneWindowShadow) Shadows.shadowOf(mDialog.getWindow())).mLayoutParams;
    }

    MyPhoneWindowShadow getShadowWindow() {
        return ((MyPhoneWindowShadow) Shadows.shadowOf(mDialog.getWindow()));
    }

    /**
     * Host impl that counts calls to it.
     */
    class HostMock implements DialogOverlayCore.Host {
        private Surface mSurface;
        private int mDestroyedCount;
        private int mWaitCloseCount;
        private int mEnforceCloseCount;

        @Override
        public void onSurfaceReady(Surface surface) {
            mSurface = surface;
        }

        @Override
        public void onOverlayDestroyed() {
            mDestroyedCount++;
        }

        @Override
        public void waitForClose() {
            mWaitCloseCount++;
        }

        @Override
        public void enforceClose() {
            mEnforceCloseCount++;
        }

        public Surface surface() {
            return mSurface;
        }

        public int destroyedCount() {
            return mDestroyedCount;
        }

        public int waitCloseCount() {
            return mWaitCloseCount;
        }

        public int enforceCloseCount() {
            return mEnforceCloseCount;
        }
    };

    HostMock mHost = new HostMock();

    // Send a window token and provide the surface, so that the overlay is ready for use.
    void sendTokenAndSurface() {
        mCore.onWindowToken(mWindowToken);
        // Make sure that somebody called takeSurface.
        assertNotNull(holderCallback());

        checkDialogIsShown();

        // Provide the Android Surface.
        holderCallback().surfaceCreated(mHolder);

        // The host should have been told about the surface.
        assertEquals(mSurface, mHost.surface());
    }

    // Verify that the dialog has been shown.
    void checkDialogIsShown() {
        assertEquals(mDialog, ShadowDialog.getShownDialogs().get(0));
    }

    // Verify that the dialog is not currently shown.  Note that dismiss() doesn't remove it from
    // the shown dialog list in Robolectric, so we check for "was never shown or was dismissed".
    void checkDialogIsNotShown() {
        assertTrue(ShadowDialog.getShownDialogs().size() == 0
                || Shadows.shadowOf(mDialog).hasBeenDismissed());
    }

    // Verify that |mCore| signaled that the overlay was lost to|mHost|.
    void checkOverlayWasDestroyed() {
        // |mCore| should have notified the host that it has been destroyed, and also waited for
        // the host to signal that the client released it.
        assertEquals(1, mHost.destroyedCount());
        checkDialogIsNotShown();
    }

    // Check that releasing an overlay before getting a window token works.
    @Test
    @Config(shadows = {MyPhoneWindowShadow.class})
    public void testReleaseImmediately() {
        // Release the overlay.  |mCore| shouldn't notify us, since we released it.
        createOverlay();
        mCore.release();
        checkOverlayDidntCall();
        checkDialogIsNotShown();
    }

    // Create a dialog, then send it a token.  Verify that it's shown.
    @Test
    @Config(shadows = {MyPhoneWindowShadow.class})
    public void testTokenThenRelease() {
        createOverlay();
        mCore.onWindowToken(mWindowToken);
        checkDialogIsShown();

        // Release the surface.  |mHost| shouldn't be notified, nor should it wait for cleanup.
        // Note: it might be okay if it checks for cleanup, since cleanup would be complete after
        // we call release().  However, it's not needed, so we enforce that it isn't.
        mCore.release();
        checkOverlayDidntCall();
        checkDialogIsNotShown();
    }

    // Create a dialog, send a token, send a surface, then release it.
    @Test
    @Config(shadows = {MyPhoneWindowShadow.class})
    public void testSurfaceThenRelease() {
        createOverlay();
        sendTokenAndSurface();

        mCore.release();
        assertEquals(0, mHost.destroyedCount());
        assertEquals(0, mHost.waitCloseCount());
        assertEquals(0, mHost.enforceCloseCount());
        checkDialogIsNotShown();
    }

    // Create a dialog, send a surface, then destroy the surface.
    @Test
    @Config(shadows = {MyPhoneWindowShadow.class})
    public void testSurfaceThenDestroy() {
        createOverlay();
        sendTokenAndSurface();

        // Destroy the surface.
        holderCallback().surfaceDestroyed(mHolder);
        // |mCore| should have waited for cleanup during surfaceDestroyed.
        assertEquals(1, mHost.waitCloseCount());
        // Since we waited for cleanup, also pretend that the release was posted during the wait and
        // will arrive after the wait completes.
        mCore.release();
        assertEquals(1, mHost.enforceCloseCount());

        checkOverlayWasDestroyed();
    }

    // Test that we're notified when the window token changes.
    @Test
    @Config(shadows = {MyPhoneWindowShadow.class})
    public void testChangeWindowToken() {
        createOverlay();
        sendTokenAndSurface();

        // Change the window token.
        mCore.onWindowToken(new Binder());

        checkOverlayWasDestroyed();
    }

    // Test that we're notified when the window token is lost.
    @Test
    @Config(shadows = {MyPhoneWindowShadow.class})
    public void testLoseWindowToken() {
        createOverlay();
        sendTokenAndSurface();

        // Remove the window token.
        mCore.onWindowToken(null);

        checkOverlayWasDestroyed();
    }

    // Test that the layout params reflect TYPE_APPLICATION_MEDIA, and that it its geometry matches
    // what we requested.
    @Test
    @Config(shadows = {MyPhoneWindowShadow.class})
    public void testOverlayTypeAndGeometry() {
        createOverlay();
        mCore.onWindowToken(mWindowToken);
        assertEquals(WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA, layoutParams().type);
        assertEquals(mConfig.rect.x, layoutParams().x);
        assertEquals(mConfig.rect.y, layoutParams().y);
        assertEquals(mConfig.rect.width, layoutParams().width);
        assertEquals(mConfig.rect.height, layoutParams().height);
    }

    // Test that the layout params reflect TYPE_APPLICATION_PANEL when we request it.
    @Test
    @Config(shadows = {MyPhoneWindowShadow.class})
    public void testOverlayAsPanel() {
        mAsPanel = true;
        createOverlay();
        mCore.onWindowToken(mWindowToken);
        assertEquals(layoutParams().type, WindowManager.LayoutParams.TYPE_APPLICATION_PANEL);
    }

    @Test
    @Config(shadows = {MyPhoneWindowShadow.class})
    public void testNoParamsUpdateForSamePositionRect() {
        createOverlay();
        mCore.onWindowToken(mWindowToken);
        assertTrue(getShadowWindow().mDidUpdateParams);

        // Update with the same rect, it should not update the window params.
        getShadowWindow().mDidUpdateParams = false;
        mCore.layoutSurface(mConfig.rect);
        assertFalse(getShadowWindow().mDidUpdateParams);
    }
}
