/*
 * Copyright (C) 2022 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 androidx.constraintlayout.compose

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material.LocalTextStyle
import androidx.compose.material.Text
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Person
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.layout.boundsInParent
import androidx.compose.ui.layout.layoutId
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInParent
import androidx.compose.ui.layout.positionInRoot
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.test.getUnclippedBoundsInRoot
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithTag
import androidx.compose.ui.test.onNodeWithText
import androidx.compose.ui.text.PlatformTextStyle
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntRect
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.round
import androidx.compose.ui.unit.roundToIntRect
import androidx.compose.ui.unit.size
import androidx.compose.ui.unit.sp
import androidx.constraintlayout.compose.test.R
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.MediumTest
import kotlin.math.roundToInt
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
import kotlin.test.assertTrue
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith

@OptIn(ExperimentalMotionApi::class)
@MediumTest
@RunWith(AndroidJUnit4::class)
internal class MotionLayoutTest {
    @get:Rule
    val rule = createComposeRule()

    /**
     * Tests that [MotionLayoutScope.customFontSize] works as expected.
     *
     * See custom_text_size_scene.json5
     */
    @Test
    fun testCustomTextSize() {
        var animateToEnd by mutableStateOf(false)
        rule.setContent {
            val progress by animateFloatAsState(targetValue = if (animateToEnd) 1.0f else 0f)
            CustomTextSize(
                modifier = Modifier.size(200.dp),
                progress = progress
            )
        }
        rule.waitForIdle()

        var usernameSize = rule.onNodeWithTag("username").getUnclippedBoundsInRoot().size

        // TextSize is 18sp at the start. Since getting the resulting dimensions of the text is not
        // straightforward, the values were obtained by running the test
        assertEquals(55.dp.value, usernameSize.width.value, absoluteTolerance = 0.5f)
        assertEquals(25.dp.value, usernameSize.height.value, absoluteTolerance = 0.5f)

        animateToEnd = true
        rule.waitForIdle()

        usernameSize = rule.onNodeWithTag("username").getUnclippedBoundsInRoot().size

        // TextSize is 12sp at the end. Results in approx. 66% of the original text height
        assertEquals(35.dp.value, usernameSize.width.value, absoluteTolerance = 0.5f)
        assertEquals(17.dp.value, usernameSize.height.value, absoluteTolerance = 0.5f)
    }

    @Test
    fun testCustomKeyFrameAttributes() {
        val progress: MutableState<Float> = mutableStateOf(0f)
        rule.setContent {
            MotionLayout(
                motionScene = MotionScene {
                    val element = createRefFor("element")
                    defaultTransition(
                        from = constraintSet {
                            constrain(element) {
                                customColor("color", Color.White)
                                customDistance("distance", 0.dp)
                                customFontSize("fontSize", 0.sp)
                                customInt("int", 0)
                            }
                        },
                        to = constraintSet {
                            constrain(element) {
                                customColor("color", Color.Black)
                                customDistance("distance", 10.dp)
                                customFontSize("fontSize", 20.sp)
                                customInt("int", 30)
                            }
                        }
                    ) {
                        keyAttributes(element) {
                            frame(50) {
                                customColor("color", Color.Red)
                                customDistance("distance", 20.dp)
                                customFontSize("fontSize", 30.sp)
                                customInt("int", 40)
                            }
                        }
                    }
                },
                progress = progress.value,
                modifier = Modifier.size(200.dp)
            ) {
                val props = customProperties(id = "element")
                Column(Modifier.layoutId("element")) {
                    Text(
                        text = "1) Color: #${props.color("color").toHexString()}"
                    )
                    Text(
                        text = "2) Distance: ${props.distance("distance")}"
                    )
                    Text(
                        text = "3) FontSize: ${props.fontSize("fontSize")}"
                    )
                    Text(
                        text = "4) Int: ${props.int("int")}"
                    )

                    // Missing properties
                    Text(
                        text = "5) Color: #${props.color("a").toHexString()}"
                    )
                    Text(
                        text = "6) Distance: ${props.distance("b")}"
                    )
                    Text(
                        text = "7) FontSize: ${props.fontSize("c")}"
                    )
                    Text(
                        text = "8) Int: ${props.int("d")}"
                    )
                }
            }
        }
        rule.waitForIdle()

        progress.value = 0.25f
        rule.waitForIdle()
        rule.onNodeWithText("1) Color: #ffffbaba").assertExists()
        rule.onNodeWithText("2) Distance: 10.0.dp").assertExists()
        rule.onNodeWithText("3) FontSize: 15.0.sp").assertExists()
        rule.onNodeWithText("4) Int: 20").assertExists()

        // Undefined custom properties
        rule.onNodeWithText("5) Color: #0").assertExists()
        rule.onNodeWithText("6) Distance: Dp.Unspecified").assertExists()
        rule.onNodeWithText("7) FontSize: NaN.sp").assertExists()
        rule.onNodeWithText("8) Int: 0").assertExists()

        progress.value = 0.75f
        rule.waitForIdle()
        rule.onNodeWithText("1) Color: #ffba0000").assertExists()
        rule.onNodeWithText("2) Distance: 15.0.dp").assertExists()
        rule.onNodeWithText("3) FontSize: 25.0.sp").assertExists()
        rule.onNodeWithText("4) Int: 35").assertExists()

        // Undefined custom properties
        rule.onNodeWithText("5) Color: #0").assertExists()
        rule.onNodeWithText("6) Distance: Dp.Unspecified").assertExists()
        rule.onNodeWithText("7) FontSize: NaN.sp").assertExists()
        rule.onNodeWithText("8) Int: 0").assertExists()
    }

    @Test
    fun testMotionLayout_withParentIntrinsics() = with(rule.density) {
        val constraintSet = ConstraintSet {
            val (one, two) = createRefsFor("one", "two")
            val horChain = createHorizontalChain(one, two, chainStyle = ChainStyle.Packed(0f))
            constrain(horChain) {
                start.linkTo(parent.start)
                end.linkTo(parent.end)
            }
            constrain(one) {
                top.linkTo(parent.top)
                bottom.linkTo(parent.bottom)
            }
            constrain(two) {
                width = Dimension.preferredWrapContent
                top.linkTo(parent.top)
                bottom.linkTo(parent.bottom)
            }
        }

        val rootBoxWidth = 200
        val box1Size = 40
        val box2Size = 70

        var rootSize = IntSize.Zero
        var mlSize = IntSize.Zero
        var box1Position = IntOffset.Zero
        var box2Position = IntOffset.Zero

        rule.setContent {
            Box(
                modifier = Modifier
                    .width(rootBoxWidth.toDp())
                    .height(IntrinsicSize.Max)
                    .background(Color.LightGray)
                    .onGloballyPositioned {
                        rootSize = it.size
                    }
            ) {
                MotionLayout(
                    start = constraintSet,
                    end = constraintSet,
                    transition = Transition {},
                    progress = 0f, // We're not testing the animation
                    modifier = Modifier
                        .fillMaxWidth()
                        .wrapContentHeight()
                        .background(Color.Yellow)
                        .onGloballyPositioned {
                            mlSize = it.size
                        }
                ) {
                    Box(
                        Modifier
                            .size(box1Size.toDp())
                            .background(Color.Green)
                            .layoutId("one")
                            .onGloballyPositioned {
                                box1Position = it
                                    .positionInRoot()
                                    .round()
                            })
                    Box(
                        Modifier
                            .size(box2Size.toDp())
                            .background(Color.Red)
                            .layoutId("two")
                            .onGloballyPositioned {
                                box2Position = it
                                    .positionInRoot()
                                    .round()
                            })
                }
            }
        }

        val expectedSize = IntSize(rootBoxWidth, box2Size)
        val expectedBox1Y = ((box2Size / 2f) - (box1Size / 2f)).roundToInt()
        rule.runOnIdle {
            assertEquals(expectedSize, rootSize)
            assertEquals(expectedSize, mlSize)
            assertEquals(IntOffset(0, expectedBox1Y), box1Position)
            assertEquals(IntOffset(box1Size, 0), box2Position)
        }
    }

    @Test
    fun testTransitionChange_hasCorrectStartAndEnd() = with(rule.density) {
        val rootWidthPx = 200
        val rootHeightPx = 50

        val scene = MotionScene {
            val circleRef = createRefFor("circle")
            val aCSetRef = constraintSet {
                constrain(circleRef) {
                    width = rootHeightPx.toDp().asDimension
                    height = rootHeightPx.toDp().asDimension
                    centerVerticallyTo(parent)
                    start.linkTo(parent.start)
                }
            }
            val bCSetRef = constraintSet {
                constrain(circleRef) {
                    width = Dimension.fillToConstraints
                    height = rootHeightPx.toDp().asDimension
                    centerTo(parent)
                }
            }
            val cCSetRef = constraintSet(extendConstraintSet = aCSetRef) {
                constrain(circleRef) {
                    clearHorizontal()
                    end.linkTo(parent.end)
                }
            }
            transition(
                from = aCSetRef,
                to = bCSetRef,
                name = "part1"
            ) {}
            transition(
                from = bCSetRef,
                to = cCSetRef,
                name = "part2"
            ) {}
        }

        val progress = mutableStateOf(0f)
        var bounds = IntRect.Zero

        rule.setContent {
            MotionLayout(
                motionScene = scene,
                progress = if (progress.value < 0.5) progress.value * 2 else progress.value * 2 - 1,
                transitionName = if (progress.value < 0.5f) "part1" else "part2",
                modifier = Modifier.size(width = rootWidthPx.toDp(), height = rootHeightPx.toDp())
            ) {
                Box(
                    modifier = Modifier
                        .layoutId("circle")
                        .background(Color.Red)
                        .onGloballyPositioned {
                            bounds = it
                                .boundsInParent()
                                .roundToIntRect()
                        }
                )
            }
        }

        rule.runOnIdle {
            assertEquals(
                expected = IntRect(IntOffset(0, 0), IntSize(rootHeightPx, rootHeightPx)),
                actual = bounds
            )
        }

        // Offset attributed to the default non-linear interpolator
        val offset = 25

        progress.value = 0.25f
        rule.runOnIdle {
            assertEquals(
                expected = IntRect(
                    offset = IntOffset(0, 0),
                    size = IntSize(rootWidthPx / 2 + offset, rootHeightPx)
                ),
                actual = bounds
            )
        }

        progress.value = 0.75f
        rule.runOnIdle {
            assertEquals(
                expected = IntRect(
                    offset = IntOffset(rootWidthPx / 2 - offset, 0),
                    size = IntSize(rootWidthPx / 2 + offset, rootHeightPx)
                ),
                actual = bounds
            )
        }
    }

    @Test
    fun testStartAndEndBoundsModifier() = with(rule.density) {
        val rootSizePx = 100
        val boxHeight = 10
        val boxWidthStartPx = 10
        val boxWidthEndPx = 70

        val boxId = "box"

        var startBoundsOfBox = Rect.Zero
        var endBoundsOfBox = Rect.Zero
        var globallyPositionedBounds = IntRect.Zero

        var boundsProvidedCount = 0

        val progress = mutableStateOf(0f)

        rule.setContent {
            MotionLayout(
                motionScene = MotionScene {
                    val box = createRefFor(boxId)
                    defaultTransition(
                        from = constraintSet {
                            constrain(box) {
                                width = boxWidthStartPx.toDp().asDimension
                                height = boxHeight.toDp().asDimension

                                top.linkTo(parent.top)
                                centerHorizontallyTo(parent)
                            }
                        },
                        to = constraintSet {
                            constrain(box) {
                                width = boxWidthEndPx.toDp().asDimension
                                height = boxHeight.toDp().asDimension

                                centerHorizontallyTo(parent)
                                bottom.linkTo(parent.bottom)
                            }
                        }
                    )
                },
                progress = progress.value,
                modifier = Modifier.size(rootSizePx.toDp())
            ) {
                Box(
                    modifier = Modifier
                        .layoutId(boxId)
                        .background(Color.Red)
                        .onStartEndBoundsChanged(boxId) { startBounds, endBounds ->
                            boundsProvidedCount++
                            startBoundsOfBox = startBounds
                            endBoundsOfBox = endBounds
                        }
                        .onGloballyPositioned {
                            globallyPositionedBounds = it
                                .boundsInParent()
                                .roundToIntRect()
                        }
                )
            }
        }
        rule.waitForIdle()

        rule.runOnIdle {
            // Values should only be assigned once, to prove that they are stable
            assertEquals(1, boundsProvidedCount)
            assertEquals(
                expected = IntRect(
                    offset = IntOffset((rootSizePx - boxWidthStartPx) / 2, 0),
                    size = IntSize(boxWidthStartPx, boxHeight)
                ),
                actual = globallyPositionedBounds
            )
            assertEquals(
                globallyPositionedBounds,
                startBoundsOfBox.roundToIntRect()
            )
        }

        progress.value = 1f

        rule.runOnIdle {
            // Values should only be assigned once, to prove that they are stable
            assertEquals(1, boundsProvidedCount)
            assertEquals(
                expected = IntRect(
                    offset = IntOffset((rootSizePx - boxWidthEndPx) / 2, rootSizePx - boxHeight),
                    size = IntSize(boxWidthEndPx, boxHeight)
                ),
                actual = globallyPositionedBounds
            )
            assertEquals(
                globallyPositionedBounds,
                endBoundsOfBox.roundToIntRect()
            )
        }
    }

    @Test
    fun testStaggeredAndCustomWeights() = with(rule.density) {
        val rootSizePx = 100
        val boxSizePx = 10
        val progress = mutableStateOf(0f)
        val staggeredValue = mutableStateOf(0.31f)
        val weights = mutableStateListOf(Float.NaN, Float.NaN, Float.NaN)

        val ids = IntArray(3) { it }
        val positions = mutableMapOf<Int, IntOffset>()

        rule.setContent {
            MotionLayout(
                motionScene = remember {
                    derivedStateOf {
                        MotionScene {
                            val refs = ids.map { createRefFor(it) }.toTypedArray()
                            defaultTransition(
                                from = constraintSet {
                                    createVerticalChain(*refs, chainStyle = ChainStyle.Packed(0.0f))
                                    refs.forEachIndexed { index, ref ->
                                        constrain(ref) {
                                            staggeredWeight = weights[index]
                                        }
                                    }
                                },
                                to = constraintSet {
                                    createVerticalChain(*refs, chainStyle = ChainStyle.Packed(0.0f))
                                    constrain(*refs) {
                                        end.linkTo(parent.end)
                                    }
                                }
                            ) {
                                staggered = staggeredValue.value
                            }
                        }
                    }
                }.value,
                progress = progress.value,
                modifier = Modifier.size(rootSizePx.toDp())
            ) {
                for (id in ids) {
                    Box(
                        Modifier
                            .size(boxSizePx.toDp())
                            .layoutId(id)
                            .onGloballyPositioned {
                                positions[id] = it
                                    .positionInParent()
                                    .round()
                            })
                }
            }
        }

        // Set the progress to just before the stagger value (0.31f)
        progress.value = 0.3f

        rule.runOnIdle {
            assertEquals(0, positions[0]!!.x)
            assertNotEquals(0, positions[1]!!.x)
            assertNotEquals(0, positions[2]!!.x)

            // Widget 2 has higher weight since it's laid out further towards the bottom
            assertTrue(positions[2]!!.x > positions[1]!!.x)
        }

        // Invert the staggering order
        staggeredValue.value = -(staggeredValue.value)

        rule.runOnIdle {
            assertNotEquals(0, positions[0]!!.x)
            assertNotEquals(0, positions[1]!!.x)
            assertEquals(0, positions[2]!!.x)

            // While inverted, widget 0 has the higher weight
            assertTrue(positions[0]!!.x > positions[1]!!.x)
        }

        // Set the widget in the middle to have the lowest weight
        weights[0] = 3f
        weights[1] = 1f
        weights[2] = 2f

        // Set the staggering order back to normal
        staggeredValue.value = -(staggeredValue.value)

        rule.runOnIdle {
            assertNotEquals(0, positions[0]!!.x)
            assertEquals(0, positions[1]!!.x)
            assertNotEquals(0, positions[2]!!.x)

            // Widget 0 has higher weight, starts earlier
            assertTrue(positions[0]!!.x > positions[2]!!.x)
        }
    }

    private fun Color.toHexString(): String = toArgb().toUInt().toString(16)
}

@OptIn(ExperimentalMotionApi::class)
@Composable
private fun CustomTextSize(modifier: Modifier, progress: Float) {
    val context = LocalContext.current
    @Suppress("DEPRECATION")
    CompositionLocalProvider(
        LocalDensity provides Density(1f, 1f),
        LocalTextStyle provides TextStyle(
            fontFamily = FontFamily.Monospace,
            fontWeight = FontWeight.Normal,
            platformStyle = PlatformTextStyle(includeFontPadding = true)
        )
    ) {
        MotionLayout(
            motionScene = MotionScene(
                content = context
                    .resources
                    .openRawResource(R.raw.custom_text_size_scene)
                    .readBytes()
                    .decodeToString()
            ),
            progress = progress,
            modifier = modifier
        ) {
            val profilePicProperties = customProperties(id = "profile_pic")
            Box(
                modifier = Modifier
                    .layoutTestId("box")
                    .background(Color.DarkGray)
            )
            Image(
                imageVector = Icons.Default.Person,
                contentDescription = null,
                modifier = Modifier
                    .clip(CircleShape)
                    .border(
                        width = 2.dp,
                        color = profilePicProperties.color("background"),
                        shape = CircleShape
                    )
                    .layoutTestId("profile_pic")
            )
            Text(
                text = "Hello",
                fontSize = customFontSize("username", "textSize"),
                modifier = Modifier.layoutTestId("username"),
                color = profilePicProperties.color("background")
            )
        }
    }
}