package com.android.systemui.util

import android.graphics.Rect
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.wm.shell.common.FloatingContentCoordinator
import org.junit.After
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith

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

    private val screenBounds = Rect(0, 0, 1000, 1000)

    private val rect100px = Rect()
    private val rect100pxFloating = FloatingRect(rect100px)

    private val rect200px = Rect()
    private val rect200pxFloating = FloatingRect(rect200px)

    private val rect300px = Rect()
    private val rect300pxFloating = FloatingRect(rect300px)

    private val floatingCoordinator = FloatingContentCoordinator()

    @Before
    fun setup() {
        rect100px.set(0, 0, 100, 100)
        rect200px.set(0, 0, 200, 200)
        rect300px.set(0, 0, 300, 300)
    }

    @After
    fun tearDown() {
        // We need to remove this stuff since it's a singleton object and it'll be there for the
        // next test.
        floatingCoordinator.onContentRemoved(rect100pxFloating)
        floatingCoordinator.onContentRemoved(rect200pxFloating)
        floatingCoordinator.onContentRemoved(rect300pxFloating)
    }

    @Test
    fun testOnContentAdded() {
        // Add rect1, and verify that the coordinator didn't move it.
        floatingCoordinator.onContentAdded(rect100pxFloating)
        assertEquals(rect100px.top, 0)

        // Add rect2, which intersects rect1. Verify that rect2 was not moved, since newly added
        // content is allowed to remain where it is. rect1 should have been moved below rect2
        // since it was in the way.
        floatingCoordinator.onContentAdded(rect200pxFloating)
        assertEquals(rect200px.top, 0)
        assertEquals(rect100px.top, 200)

        verifyRectSizes()
    }

    @Test
    fun testOnContentRemoved() {
        // Add rect1, and remove it. Then add rect2. Since rect1 was removed before that, it should
        // no longer be considered in the way, so it shouldn't move when rect2 is added.
        floatingCoordinator.onContentAdded(rect100pxFloating)
        floatingCoordinator.onContentRemoved(rect100pxFloating)
        floatingCoordinator.onContentAdded(rect200pxFloating)

        assertEquals(rect100px.top, 0)
        assertEquals(rect200px.top, 0)

        verifyRectSizes()
    }

    @Test
    fun testOnContentMoved_twoRects() {
        // Add rect1, which is at y = 0.
        floatingCoordinator.onContentAdded(rect100pxFloating)

        // Move rect2 down to 500px, where it won't conflict with rect1.
        rect200px.offsetTo(0, 500)
        floatingCoordinator.onContentAdded(rect200pxFloating)

        // Then, move it to 0px where it will absolutely conflict with rect1.
        rect200px.offsetTo(0, 0)
        floatingCoordinator.onContentMoved(rect200pxFloating)

        // The coordinator should have left rect2 alone, and moved rect1 below it. rect1 should now
        // be at y = 200.
        assertEquals(rect200px.top, 0)
        assertEquals(rect100px.top, 200)

        verifyRectSizes()

        // Move rect2 to y = 275px. Since this puts it at the bottom half of rect1, it should push
        // rect1 upward and leave rect2 alone.
        rect200px.offsetTo(0, 275)
        floatingCoordinator.onContentMoved(rect200pxFloating)

        assertEquals(rect200px.top, 275)
        assertEquals(rect100px.top, 175)

        verifyRectSizes()

        // Move rect2 to y = 110px. This makes it intersect rect1 again, but above its center of
        // mass. That means rect1 should be pushed downward.
        rect200px.offsetTo(0, 110)
        floatingCoordinator.onContentMoved(rect200pxFloating)

        assertEquals(rect200px.top, 110)
        assertEquals(rect100px.top, 310)

        verifyRectSizes()
    }

    @Test
    fun testOnContentMoved_threeRects() {
        floatingCoordinator.onContentAdded(rect100pxFloating)

        // Add rect2, which should displace rect1 to y = 200
        floatingCoordinator.onContentAdded(rect200pxFloating)
        assertEquals(rect200px.top, 0)
        assertEquals(rect100px.top, 200)

        // Add rect3, which should completely cover both rect1 and rect2. That should cause them to
        // move away. The order in which they do so is non-deterministic, so just make sure none of
        // the three Rects intersect.
        floatingCoordinator.onContentAdded(rect300pxFloating)

        assertFalse(Rect.intersects(rect100px, rect200px))
        assertFalse(Rect.intersects(rect100px, rect300px))
        assertFalse(Rect.intersects(rect200px, rect300px))

        // Move rect2 to intersect both rect1 and rect3.
        rect200px.offsetTo(0, 150)
        floatingCoordinator.onContentMoved(rect200pxFloating)

        assertFalse(Rect.intersects(rect100px, rect200px))
        assertFalse(Rect.intersects(rect100px, rect300px))
        assertFalse(Rect.intersects(rect200px, rect300px))
    }

    @Test
    fun testOnContentMoved_respectsUpperBounds() {
        // Add rect1, which is at y = 0.
        floatingCoordinator.onContentAdded(rect100pxFloating)

        // Move rect2 down to 500px, where it won't conflict with rect1.
        rect200px.offsetTo(0, 500)
        floatingCoordinator.onContentAdded(rect200pxFloating)

        // Then, move it to 90px where it will conflict with rect1, but with a center of mass below
        // that of rect1's. This would normally mean that rect1 moves upward. However, since it's at
        // the top of the screen, it should go downward instead.
        rect200px.offsetTo(0, 90)
        floatingCoordinator.onContentMoved(rect200pxFloating)

        // rect2 should have been left alone, rect1 is now below rect2 at y = 290px even though it
        // was intersected from below.
        assertEquals(rect200px.top, 90)
        assertEquals(rect100px.top, 290)
    }

    @Test
    fun testOnContentMoved_respectsLowerBounds() {
        // Put rect1 at the bottom of the screen and add it.
        rect100px.offsetTo(0, screenBounds.bottom - 100)
        floatingCoordinator.onContentAdded(rect100pxFloating)

        // Put rect2 at the bottom as well. Since its center of mass is above rect1's, rect1 would
        // normally move downward. Since it's at the bottom of the screen, it should go upward
        // instead.
        rect200px.offsetTo(0, 800)
        floatingCoordinator.onContentAdded(rect200pxFloating)

        assertEquals(rect200px.top, 800)
        assertEquals(rect100px.top, 700)
    }

    /**
     * Tests that the rect sizes didn't change when the coordinator manipulated them. This allows us
     * to assert only the value of rect.top in tests, since if top, width, and height are correct,
     * that means top/left/right/bottom are all correct.
     */
    private fun verifyRectSizes() {
        assertEquals(100, rect100px.width())
        assertEquals(200, rect200px.width())
        assertEquals(300, rect300px.width())

        assertEquals(100, rect100px.height())
        assertEquals(200, rect200px.height())
        assertEquals(300, rect300px.height())
    }

    /**
     * Helper class that uses [floatingCoordinator.findAreaForContentVertically] to move a
     * Rect when needed.
     */
    inner class FloatingRect(
        private val underlyingRect: Rect
    ) : FloatingContentCoordinator.FloatingContent {
        override fun moveToBounds(bounds: Rect) {
            underlyingRect.set(bounds)
        }

        override fun getAllowedFloatingBoundsRegion(): Rect {
            return screenBounds
        }

        override fun getFloatingBoundsOnScreen(): Rect {
            return underlyingRect
        }
    }
}