/*
 * Copyright 2019 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.ui.material

import androidx.test.filters.SmallTest
import androidx.compose.foundation.text.FirstBaseline
import androidx.ui.core.LayoutCoordinates
import androidx.ui.core.Modifier
import androidx.ui.core.Ref
import androidx.ui.core.onPositioned
import androidx.compose.foundation.Box
import androidx.compose.foundation.Image
import androidx.compose.foundation.Text
import androidx.ui.geometry.Offset
import androidx.ui.graphics.ImageAsset
import androidx.ui.test.assertHeightIsEqualTo
import androidx.ui.test.createComposeRule
import androidx.ui.unit.Dp
import androidx.ui.unit.IntSize
import androidx.ui.unit.dp
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import kotlin.math.roundToInt

@SmallTest
@RunWith(JUnit4::class)
class ListItemTest {

    @get:Rule
    val composeTestRule = createComposeRule()

    val icon24x24 by lazy { ImageAsset(width = 24.dp.toIntPx(), height = 24.dp.toIntPx()) }
    val icon40x40 by lazy { ImageAsset(width = 40.dp.toIntPx(), height = 40.dp.toIntPx()) }
    val icon56x56 by lazy { ImageAsset(width = 56.dp.toIntPx(), height = 56.dp.toIntPx()) }

    @Test
    fun listItem_oneLine_size() {
        val expectedHeightNoIcon = 48.dp
        composeTestRule
            .setMaterialContentForSizeAssertions {
                ListItem(text = "Primary text")
            }
            .assertHeightIsEqualTo(expectedHeightNoIcon)
            .assertWidthFillsRoot()
    }

    @Test
    fun listItem_oneLine_withIcon24_size() {
        val expectedHeightSmallIcon = 56.dp
        composeTestRule
            .setMaterialContentForSizeAssertions {
                ListItem(text = "Primary text", icon = icon24x24)
            }
            .assertHeightIsEqualTo(expectedHeightSmallIcon)
            .assertWidthFillsRoot()
    }

    @Test
    fun listItem_oneLine_withIcon56_size() {
        val expectedHeightLargeIcon = 72.dp
        composeTestRule
            .setMaterialContentForSizeAssertions {
                ListItem(text = "Primary text", icon = icon56x56)
            }
            .assertHeightIsEqualTo(expectedHeightLargeIcon)
            .assertWidthFillsRoot()
    }

    @Test
    fun listItem_twoLine_size() {
        val expectedHeightNoIcon = 64.dp
        composeTestRule
            .setMaterialContentForSizeAssertions {
                ListItem(text = "Primary text", secondaryText = "Secondary text")
            }
            .assertHeightIsEqualTo(expectedHeightNoIcon)
            .assertWidthFillsRoot()
    }

    @Test
    fun listItem_twoLine_withIcon_size() {
        val expectedHeightWithIcon = 72.dp

        composeTestRule
            .setMaterialContentForSizeAssertions {
                ListItem(
                    text = "Primary text",
                    secondaryText = "Secondary text",
                    icon = icon24x24
                )
            }
            .assertHeightIsEqualTo(expectedHeightWithIcon)
            .assertWidthFillsRoot()
    }

    @Test
    fun listItem_threeLine_size() {
        val expectedHeight = 88.dp
        composeTestRule
            .setMaterialContentForSizeAssertions {
                ListItem(
                    overlineText = "OVERLINE",
                    text = "Primary text",
                    secondaryText = "Secondary text"
                )
            }
            .assertHeightIsEqualTo(expectedHeight)
            .assertWidthFillsRoot()
    }

    @Test
    fun listItem_threeLine_noSingleLine_size() {
        val expectedHeight = 88.dp
        composeTestRule
            .setMaterialContentForSizeAssertions {
                ListItem(
                    text = "Primary text",
                    secondaryText = "Secondary text with long text",
                    singleLineSecondaryText = false
                )
            }
            .assertHeightIsEqualTo(expectedHeight)
            .assertWidthFillsRoot()
    }

    @Test
    fun listItem_threeLine_metaText_size() {
        val expectedHeight = 88.dp
        composeTestRule
            .setMaterialContentForSizeAssertions {
                ListItem(
                    overlineText = "OVERLINE",
                    text = "Primary text",
                    secondaryText = "Secondary text",
                    metaText = "meta"
                )
            }
            .assertHeightIsEqualTo(expectedHeight)
            .assertWidthFillsRoot()
    }

    @Test
    fun listItem_threeLine_noSingleLine_metaText_size() {
        val expectedHeight = 88.dp
        composeTestRule
            .setMaterialContentForSizeAssertions {
                ListItem(
                    text = "Primary text",
                    secondaryText = "Secondary text with long text",
                    singleLineSecondaryText = false,
                    metaText = "meta"
                )
            }
            .assertHeightIsEqualTo(expectedHeight)
            .assertWidthFillsRoot()
    }

    @Test
    fun listItem_oneLine_positioning_noIcon() {
        val listItemHeight = 48.dp
        val expectedLeftPadding = 16.dp
        val expectedRightPadding = 16.dp

        val textPosition = Ref<Offset>()
        val textSize = Ref<IntSize>()
        val trailingPosition = Ref<Offset>()
        val trailingSize = Ref<IntSize>()
        composeTestRule.setMaterialContent {
            Box {
                ListItem(
                    text = { Text("Primary text", saveLayout(textPosition, textSize)) },
                    trailing = {
                        Image(icon24x24, saveLayout(trailingPosition, trailingSize))
                    }
                )
            }
        }
        composeTestRule.runOnIdleWithDensity {
            assertThat(textPosition.value!!.x).isEqualTo(expectedLeftPadding.toIntPx()
                .toFloat())
            assertThat(textPosition.value!!.y).isEqualTo(
                ((listItemHeight.toIntPx() - textSize.value!!.height) / 2f).roundToInt().toFloat()
            )
            val dm = composeTestRule.displayMetrics
            assertThat(trailingPosition.value!!.x).isEqualTo(
                dm.widthPixels - trailingSize.value!!.width -
                        expectedRightPadding.toIntPx().toFloat()
            )
            assertThat(trailingPosition.value!!.y).isEqualTo(
                ((listItemHeight.toIntPx() - trailingSize.value!!.height) / 2f).roundToInt()
                    .toFloat()
            )
        }
    }

    @Test
    fun listItem_oneLine_positioning_withIcon() {
        val listItemHeight = 56.dp
        val expectedLeftPadding = 16.dp
        val expectedTextLeftPadding = 32.dp

        val textPosition = Ref<Offset>()
        val textSize = Ref<IntSize>()
        val iconPosition = Ref<Offset>()
        val iconSize = Ref<IntSize>()
        composeTestRule.setMaterialContent {
            Box {
                ListItem(
                    text = { Text("Primary text", saveLayout(textPosition, textSize)) },
                    icon = { Image(icon24x24, saveLayout(iconPosition, iconSize)) }
                )
            }
        }
        composeTestRule.runOnIdleWithDensity {
            assertThat(iconPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat()
            )
            assertThat(iconPosition.value!!.y).isEqualTo(
                ((listItemHeight.toIntPx() - iconSize.value!!.height) / 2f).roundToInt().toFloat()
            )
            assertThat(textPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat() +
                        iconSize.value!!.width +
                        expectedTextLeftPadding.toIntPx().toFloat()
            )
            assertThat(textPosition.value!!.y).isEqualTo(
                ((listItemHeight.toIntPx() - textSize.value!!.height) / 2f).roundToInt().toFloat()
            )
        }
    }

    @Test
    fun listItem_twoLine_positioning_noIcon() {
        val expectedLeftPadding = 16.dp
        val expectedRightPadding = 16.dp
        val expectedTextBaseline = 28.dp
        val expectedSecondaryTextBaselineOffset = 20.dp

        val textPosition = Ref<Offset>()
        val textBaseline = Ref<Float>()
        val textSize = Ref<IntSize>()
        val secondaryTextPosition = Ref<Offset>()
        val secondaryTextBaseline = Ref<Float>()
        val secondaryTextSize = Ref<IntSize>()
        val trailingPosition = Ref<Offset>()
        val trailingBaseline = Ref<Float>()
        val trailingSize = Ref<IntSize>()
        composeTestRule.setMaterialContent {
            Box {
                ListItem(
                    text = {
                        Text("Primary text", saveLayout(textPosition, textSize, textBaseline))
                    },
                    secondaryText = {
                        Text(
                            "Secondary text",
                            saveLayout(
                                secondaryTextPosition,
                                secondaryTextSize,
                                secondaryTextBaseline
                            )
                        )
                    },
                    trailing = {
                        Text("meta", saveLayout(trailingPosition, trailingSize, trailingBaseline))
                    }
                )
            }
        }
        composeTestRule.runOnIdleWithDensity {
            assertThat(textPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat()
            )
            assertThat(textBaseline.value!!).isEqualTo(
                expectedTextBaseline.toIntPx().toFloat()
            )
            assertThat(secondaryTextPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat()
            )
            assertThat(secondaryTextBaseline.value!!).isEqualTo(
                expectedTextBaseline.toIntPx().toFloat() +
                        expectedSecondaryTextBaselineOffset.toIntPx().toFloat()
            )
            val dm = composeTestRule.displayMetrics
            assertThat(trailingPosition.value!!.x).isEqualTo(
                dm.widthPixels - trailingSize.value!!.width -
                        expectedRightPadding.toIntPx().toFloat()
            )
            assertThat(trailingBaseline.value!!).isEqualTo(
                expectedTextBaseline.toIntPx().toFloat()
            )
        }
    }

    @Test
    fun listItem_twoLine_positioning_withSmallIcon() {
        val expectedLeftPadding = 16.dp
        val expectedIconTopPadding = 16.dp
        val expectedContentLeftPadding = 32.dp
        val expectedTextBaseline = 32.dp
        val expectedSecondaryTextBaselineOffset = 20.dp

        val textPosition = Ref<Offset>()
        val textBaseline = Ref<Float>()
        val textSize = Ref<IntSize>()
        val secondaryTextPosition = Ref<Offset>()
        val secondaryTextBaseline = Ref<Float>()
        val secondaryTextSize = Ref<IntSize>()
        val iconPosition = Ref<Offset>()
        val iconSize = Ref<IntSize>()
        composeTestRule.setMaterialContent {
            Box {
                ListItem(
                    text = {
                        Text("Primary text", saveLayout(textPosition, textSize, textBaseline))
                    },
                    secondaryText = {
                        Text(
                            "Secondary text",
                            saveLayout(
                                secondaryTextPosition,
                                secondaryTextSize,
                                secondaryTextBaseline
                            )
                        )
                    },
                    icon = {
                        Image(icon24x24, saveLayout(iconPosition, iconSize))
                    }
                )
            }
        }
        composeTestRule.runOnIdleWithDensity {
            assertThat(textPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat() + iconSize.value!!.width +
                        expectedContentLeftPadding.toIntPx().toFloat()
            )
            assertThat(textBaseline.value!!).isEqualTo(
                expectedTextBaseline.toIntPx().toFloat()
            )
            assertThat(secondaryTextPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat() +
                        iconSize.value!!.width +
                        expectedContentLeftPadding.toIntPx().toFloat()
            )
            assertThat(secondaryTextBaseline.value!!).isEqualTo(
                expectedTextBaseline.toIntPx().toFloat() +
                        expectedSecondaryTextBaselineOffset.toIntPx().toFloat()
            )
            assertThat(iconPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat()
            )
            assertThat(iconPosition.value!!.y).isEqualTo(
                expectedIconTopPadding.toIntPx().toFloat()
            )
        }
    }

    @Test
    fun listItem_twoLine_positioning_withLargeIcon() {
        val listItemHeight = 72.dp
        val expectedLeftPadding = 16.dp
        val expectedIconTopPadding = 16.dp
        val expectedContentLeftPadding = 16.dp
        val expectedTextBaseline = 32.dp
        val expectedSecondaryTextBaselineOffset = 20.dp
        val expectedRightPadding = 16.dp

        val textPosition = Ref<Offset>()
        val textBaseline = Ref<Float>()
        val textSize = Ref<IntSize>()
        val secondaryTextPosition = Ref<Offset>()
        val secondaryTextBaseline = Ref<Float>()
        val secondaryTextSize = Ref<IntSize>()
        val iconPosition = Ref<Offset>()
        val iconSize = Ref<IntSize>()
        val trailingPosition = Ref<Offset>()
        val trailingSize = Ref<IntSize>()
        composeTestRule.setMaterialContent {
            Box {
                ListItem(
                    text = {
                        Text("Primary text", saveLayout(textPosition, textSize, textBaseline))
                    },
                    secondaryText = {
                        Text(
                            "Secondary text",
                            saveLayout(
                                secondaryTextPosition,
                                secondaryTextSize,
                                secondaryTextBaseline
                            )
                        )
                    },
                    icon = {
                        Image(icon40x40, saveLayout(iconPosition, iconSize))
                    },
                    trailing = {
                        Image(icon24x24, saveLayout(trailingPosition, trailingSize))
                    }
                )
            }
        }
        composeTestRule.runOnIdleWithDensity {
            assertThat(textPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat() + iconSize.value!!.width +
                        expectedContentLeftPadding.toIntPx().toFloat()
            )
            assertThat(textBaseline.value!!).isEqualTo(
                expectedTextBaseline.toIntPx().toFloat()
            )
            assertThat(secondaryTextPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat() +
                        iconSize.value!!.width +
                        expectedContentLeftPadding.toIntPx().toFloat()
            )
            assertThat(secondaryTextBaseline.value!!).isEqualTo(
                expectedTextBaseline.toIntPx().toFloat() +
                        expectedSecondaryTextBaselineOffset.toIntPx().toFloat()
            )
            assertThat(iconPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat()
            )
            assertThat(iconPosition.value!!.y).isEqualTo(
                expectedIconTopPadding.toIntPx().toFloat()
            )
            val dm = composeTestRule.displayMetrics
            assertThat(trailingPosition.value!!.x).isEqualTo(
                dm.widthPixels - trailingSize.value!!.width -
                        expectedRightPadding.toIntPx().toFloat()
            )
            assertThat(trailingPosition.value!!.y).isEqualTo(
                ((listItemHeight.toIntPx() - trailingSize.value!!.height) / 2).toFloat()
            )
        }
    }

    @Test
    fun listItem_threeLine_positioning_noOverline_metaText() {
        val expectedLeftPadding = 16.dp
        val expectedIconTopPadding = 16.dp
        val expectedContentLeftPadding = 32.dp
        val expectedTextBaseline = 28.dp
        val expectedSecondaryTextBaselineOffset = 20.dp
        val expectedRightPadding = 16.dp

        val textPosition = Ref<Offset>()
        val textBaseline = Ref<Float>()
        val textSize = Ref<IntSize>()
        val secondaryTextPosition = Ref<Offset>()
        val secondaryTextBaseline = Ref<Float>()
        val secondaryTextSize = Ref<IntSize>()
        val iconPosition = Ref<Offset>()
        val iconSize = Ref<IntSize>()
        val trailingPosition = Ref<Offset>()
        val trailingSize = Ref<IntSize>()
        composeTestRule.setMaterialContent {
            Box {
                ListItem(
                    text = {
                        Text("Primary text", saveLayout(textPosition, textSize, textBaseline))
                    },
                    secondaryText = {
                        Text(
                            "Secondary text",
                            saveLayout(
                                secondaryTextPosition,
                                secondaryTextSize,
                                secondaryTextBaseline
                            )
                        )
                    },
                    singleLineSecondaryText = false,
                    icon = {
                        Image(icon24x24, saveLayout(iconPosition, iconSize))
                    },
                    trailing = {
                        Image(icon24x24, saveLayout(trailingPosition, trailingSize))
                    }
                )
            }
        }
        composeTestRule.runOnIdleWithDensity {
            assertThat(textPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat() + iconSize.value!!.width +
                        expectedContentLeftPadding.toIntPx().toFloat()
            )
            assertThat(textBaseline.value!!).isEqualTo(
                expectedTextBaseline.toIntPx().toFloat()
            )
            assertThat(secondaryTextPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat() + iconSize.value!!.width +
                        expectedContentLeftPadding.toIntPx().toFloat()
            )
            assertThat(secondaryTextBaseline.value!!).isEqualTo(
                expectedTextBaseline.toIntPx().toFloat() +
                        expectedSecondaryTextBaselineOffset.toIntPx().toFloat()
            )
            assertThat(iconPosition.value!!.x).isEqualTo(expectedLeftPadding.toIntPx().toFloat())
            assertThat(iconPosition.value!!.y).isEqualTo(
                expectedIconTopPadding.toIntPx().toFloat()
            )
            val dm = composeTestRule.displayMetrics
            assertThat(trailingPosition.value!!.x).isEqualTo(
                dm.widthPixels - trailingSize.value!!.width.toFloat() -
                        expectedRightPadding.toIntPx().toFloat()
            )
            assertThat(trailingPosition.value!!.y).isEqualTo(
                expectedIconTopPadding.toIntPx().toFloat()
            )
        }
    }

    @Test
    fun listItem_threeLine_positioning_overline_trailingIcon() {
        val expectedLeftPadding = 16.dp
        val expectedIconTopPadding = 16.dp
        val expectedContentLeftPadding = 16.dp
        val expectedOverlineBaseline = 28.dp
        val expectedTextBaselineOffset = 20.dp
        val expectedSecondaryTextBaselineOffset = 20.dp
        val expectedRightPadding = 16.dp

        val textPosition = Ref<Offset>()
        val textBaseline = Ref<Float>()
        val textSize = Ref<IntSize>()
        val overlineTextPosition = Ref<Offset>()
        val overlineTextBaseline = Ref<Float>()
        val overlineTextSize = Ref<IntSize>()
        val secondaryTextPosition = Ref<Offset>()
        val secondaryTextBaseline = Ref<Float>()
        val secondaryTextSize = Ref<IntSize>()
        val iconPosition = Ref<Offset>()
        val iconSize = Ref<IntSize>()
        val trailingPosition = Ref<Offset>()
        val trailingSize = Ref<IntSize>()
        val trailingBaseline = Ref<Float>()
        composeTestRule.setMaterialContent {
            Box {
                ListItem(
                    overlineText = {
                        Text(
                            "OVERLINE",
                            saveLayout(
                                overlineTextPosition,
                                overlineTextSize,
                                overlineTextBaseline
                            )
                        )
                    },
                    text = {
                        Text("Primary text", saveLayout(textPosition, textSize, textBaseline))
                    },
                    secondaryText = {
                        Text(
                            "Secondary text",
                            saveLayout(
                                secondaryTextPosition,
                                secondaryTextSize,
                                secondaryTextBaseline
                            )
                        )
                    },
                    icon = {
                        Image(
                            icon40x40,
                            saveLayout(iconPosition, iconSize)
                        )
                    },
                    trailing = {
                        Text(
                            "meta",
                            saveLayout(
                                trailingPosition,
                                trailingSize,
                                trailingBaseline
                            )
                        )
                    }
                )
            }
        }
        composeTestRule.runOnIdleWithDensity {
            assertThat(textPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat() +
                        iconSize.value!!.width +
                        expectedContentLeftPadding.toIntPx().toFloat()
            )
            assertThat(textBaseline.value!!).isEqualTo(
                expectedOverlineBaseline.toIntPx().toFloat() +
                        expectedTextBaselineOffset.toIntPx().toFloat()
            )
            assertThat(overlineTextPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat() +
                        iconSize.value!!.width +
                        expectedContentLeftPadding.toIntPx().toFloat()
            )
            assertThat(overlineTextBaseline.value!!).isEqualTo(
                expectedOverlineBaseline.toIntPx().toFloat()
            )
            assertThat(secondaryTextPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat() +
                        iconSize.value!!.width +
                        expectedContentLeftPadding.toIntPx().toFloat()
            )
            assertThat(secondaryTextBaseline.value!!).isEqualTo(
                expectedOverlineBaseline.toIntPx().toFloat() +
                        expectedTextBaselineOffset.toIntPx().toFloat() +
                        expectedSecondaryTextBaselineOffset.toIntPx().toFloat()
            )
            assertThat(iconPosition.value!!.x).isEqualTo(
                expectedLeftPadding.toIntPx().toFloat()
            )
            assertThat(iconPosition.value!!.y).isEqualTo(
                expectedIconTopPadding.toIntPx().toFloat()
            )
            val dm = composeTestRule.displayMetrics
            assertThat(trailingPosition.value!!.x).isEqualTo(
                dm.widthPixels - trailingSize.value!!.width -
                        expectedRightPadding.toIntPx().toFloat()
            )
            assertThat(trailingBaseline.value!!).isEqualTo(
                expectedOverlineBaseline.toIntPx().toFloat()
            )
        }
    }

    private fun Dp.toIntPx() = (this.value * composeTestRule.density.density).roundToInt()

    private fun saveLayout(
        coords: Ref<Offset>,
        size: Ref<IntSize>,
        baseline: Ref<Float> = Ref()
    ): Modifier = Modifier.onPositioned { coordinates: LayoutCoordinates ->
        coords.value = coordinates.localToRoot(Offset.Zero)
        baseline.value = coordinates[FirstBaseline].toFloat() + coords.value!!.y
        size.value = coordinates.size
    }
}
