/*
 * 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.compose.ui.text

import androidx.compose.runtime.Immutable
import androidx.compose.runtime.Stable
import androidx.compose.ui.text.caches.LruCache
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Density
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.constrain
import kotlin.math.ceil

/**
 * Use cases that converge to this number;
 * - Static text is drawn on canvas for legend and labels.
 * - Text toggles between enumerated states bold, italic.
 * - Multiple texts drawn but only their colors are animated.
 *
 * If text layout is always called with different inputs, this number is a good stopping point so
 * that cache does not becomes unnecessarily large and miss penalty stays low. Of course developers
 * should be aware that in a use case like that the cache should explicitly be disabled.
 */
private val DefaultCacheSize = 8

/**
 * TextMeasurer is responsible for measuring a text in its entirety so that it's ready to be drawn.
 *
 * A TextMeasurer instance should be created via `androidx.compose.ui.rememberTextMeasurer` in a
 * Composable context to use fallback values from default composition locals.
 *
 * Text layout is a computationally expensive task. Therefore, this class holds an internal LRU
 * Cache of layout input and output pairs to optimize the repeated measure calls that use the same
 * input parameters.
 *
 * Although most input parameters have a direct influence on layout, some parameters like color,
 * brush, and shadow can be ignored during layout and set at the end. Using TextMeasurer with
 * appropriate [cacheSize] should provide significant improvements while animating
 * non-layout-affecting attributes like color.
 *
 * Moreover, if there is a need to render multiple static texts, you can provide the number of texts
 * by [cacheSize] and their layouts should be cached for repeating calls. Be careful that even a
 * slight change in input parameters like fontSize, maxLines, an additional character in text would
 * create a distinct set of input parameters. As a result, a new layout would be calculated and a
 * new set of input and output pair would be placed in LRU Cache, possibly evicting an earlier
 * result.
 *
 * [FontFamily.Resolver], [LayoutDirection], and [Density] are required parameters to construct a
 * text layout but they have no safe fallbacks outside of composition. These parameters must be
 * provided during the construction of a TextMeasurer to be used as default values when they are
 * skipped in [TextMeasurer.measure] call.
 *
 * @param defaultFontFamilyResolver to be used to load fonts given in [TextStyle] and [SpanStyle]s
 *   in [AnnotatedString].
 * @param defaultLayoutDirection layout direction of the measurement environment.
 * @param defaultDensity density of the measurement environment. Density controls the scaling factor
 *   for fonts.
 * @param cacheSize Capacity of internal cache inside TextMeasurer. Size unit is the number of
 *   unique text layout inputs that are measured. Value of this parameter highly depends on the
 *   consumer use case. Provide a cache size that is in line with how many distinct text layouts are
 *   going to be calculated by this measurer repeatedly. If you are animating font attributes, or
 *   any other layout affecting input, cache can be skipped because most repeated measure calls
 *   would miss the cache.
 */
@Immutable
class TextMeasurer
constructor(
    private val defaultFontFamilyResolver: FontFamily.Resolver,
    private val defaultDensity: Density,
    private val defaultLayoutDirection: LayoutDirection,
    private val cacheSize: Int = DefaultCacheSize
) {
    private val textLayoutCache: TextLayoutCache? =
        if (cacheSize > 0) {
            TextLayoutCache(cacheSize)
        } else null

    /**
     * Creates a [TextLayoutResult] according to given parameters.
     *
     * This function supports laying out text that consists of multiple paragraphs, includes
     * placeholders, wraps around soft line breaks, and might overflow outside the specified size.
     *
     * Most parameters for text affect the final text layout. One pixel change in [constraints]
     * boundaries can displace a word to another line which would cause a chain reaction that
     * completely changes how text is rendered.
     *
     * On the other hand, some attributes only play a role when drawing the created text layout. For
     * example text layout can be created completely in black color but we can apply
     * [TextStyle.color] later in draw phase. This also means that animating text color shouldn't
     * invalidate text layout.
     *
     * Thus, [textLayoutCache] helps in the process of converting a set of text layout inputs to a
     * text layout while ignoring non-layout-affecting attributes. Iterative calls that use the same
     * input parameters should benefit from substantial performance improvements.
     *
     * @param text the text to be laid out
     * @param style the [TextStyle] to be applied to the whole text
     * @param overflow How visual overflow should be handled.
     * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in
     *   the text will be positioned as if there was unlimited horizontal space. If [softWrap] is
     *   false, [overflow] and TextAlign may have unexpected effects.
     * @param maxLines An optional maximum number of lines for the text to span, wrapping if
     *   necessary. If the text exceeds the given number of lines, it will be truncated according to
     *   [overflow] and [softWrap]. If it is not null, then it must be greater than zero.
     * @param placeholders a list of [Placeholder]s that specify ranges of text which will be
     *   skipped during layout and replaced with [Placeholder]. It's required that the range of each
     *   [Placeholder] doesn't cross paragraph boundary, otherwise [IllegalArgumentException] is
     *   thrown.
     * @param constraints how wide and tall the text is allowed to be. [Constraints.maxWidth] will
     *   define the width of the MultiParagraph. [Constraints.maxHeight] helps defining the number
     *   of lines that fit with ellipsis is true. [Constraints.minWidth] defines the minimum width
     *   the resulting [TextLayoutResult.size] will report. [Constraints.minHeight] is no-op.
     * @param layoutDirection layout direction of the measurement environment. If not specified,
     *   defaults to the value that was given during initialization of this [TextMeasurer].
     * @param density density of the measurement environment. If not specified, defaults to the
     *   value that was given during initialization of this [TextMeasurer].
     * @param fontFamilyResolver to be used to load the font given in [SpanStyle]s. If not
     *   specified, defaults to the value that was given during initialization of this
     *   [TextMeasurer].
     * @param skipCache Disables cache optimization if it is passed as true.
     * @sample androidx.compose.ui.text.samples.measureTextAnnotatedString
     */
    @Stable
    fun measure(
        text: AnnotatedString,
        style: TextStyle = TextStyle.Default,
        overflow: TextOverflow = TextOverflow.Clip,
        softWrap: Boolean = true,
        maxLines: Int = Int.MAX_VALUE,
        placeholders: List<AnnotatedString.Range<Placeholder>> = emptyList(),
        constraints: Constraints = Constraints(),
        layoutDirection: LayoutDirection = this.defaultLayoutDirection,
        density: Density = this.defaultDensity,
        fontFamilyResolver: FontFamily.Resolver = this.defaultFontFamilyResolver,
        skipCache: Boolean = false
    ): TextLayoutResult {
        val requestedTextLayoutInput =
            TextLayoutInput(
                text,
                style,
                placeholders,
                maxLines,
                softWrap,
                overflow,
                density,
                layoutDirection,
                fontFamilyResolver,
                constraints
            )

        val cacheResult =
            if (!skipCache && textLayoutCache != null) {
                textLayoutCache.get(requestedTextLayoutInput)
            } else null

        return if (cacheResult != null) {
            cacheResult.copy(
                layoutInput = requestedTextLayoutInput,
                size =
                    constraints.constrain(
                        IntSize(
                            cacheResult.multiParagraph.width.ceilToInt(),
                            cacheResult.multiParagraph.height.ceilToInt()
                        )
                    )
            )
        } else {
            layout(requestedTextLayoutInput).also {
                textLayoutCache?.put(requestedTextLayoutInput, it)
            }
        }
    }

    /**
     * Creates a [TextLayoutResult] according to given parameters.
     *
     * This function supports laying out text that consists of multiple paragraphs, includes
     * placeholders, wraps around soft line breaks, and might overflow outside the specified size.
     *
     * Most parameters for text affect the final text layout. One pixel change in [constraints]
     * boundaries can displace a word to another line which would cause a chain reaction that
     * completely changes how text is rendered.
     *
     * On the other hand, some attributes only play a role when drawing the created text layout. For
     * example text layout can be created completely in black color but we can apply
     * [TextStyle.color] later in draw phase. This also means that animating text color shouldn't
     * invalidate text layout.
     *
     * Thus, [textLayoutCache] helps in the process of converting a set of text layout inputs to a
     * text layout while ignoring non-layout-affecting attributes. Iterative calls that use the same
     * input parameters should benefit from substantial performance improvements.
     *
     * @param text the text to be laid out
     * @param style the [TextStyle] to be applied to the whole text
     * @param overflow How visual overflow should be handled.
     * @param softWrap Whether the text should break at soft line breaks. If false, the glyphs in
     *   the text will be positioned as if there was unlimited horizontal space. If [softWrap] is
     *   false, [overflow] and TextAlign may have unexpected effects.
     * @param maxLines An optional maximum number of lines for the text to span, wrapping if
     *   necessary. If the text exceeds the given number of lines, it will be truncated according to
     *   [overflow] and [softWrap]. If it is not null, then it must be greater than zero.
     * @param constraints how wide and tall the text is allowed to be. [Constraints.maxWidth] will
     *   define the width of the MultiParagraph. [Constraints.maxHeight] helps defining the number
     *   of lines that fit with ellipsis is true. [Constraints.minWidth] defines the minimum width
     *   the resulting [TextLayoutResult.size] will report. [Constraints.minHeight] is no-op.
     * @param layoutDirection layout direction of the measurement environment. If not specified,
     *   defaults to the value that was given during initialization of this [TextMeasurer].
     * @param density density of the measurement environment. If not specified, defaults to the
     *   value that was given during initialization of this [TextMeasurer].
     * @param fontFamilyResolver to be used to load the font given in [SpanStyle]s. If not
     *   specified, defaults to the value that was given during initialization of this
     *   [TextMeasurer].
     * @param skipCache Disables cache optimization if it is passed as true.
     * @sample androidx.compose.ui.text.samples.measureTextStringWithConstraints
     */
    @Stable
    fun measure(
        text: String,
        style: TextStyle = TextStyle.Default,
        overflow: TextOverflow = TextOverflow.Clip,
        softWrap: Boolean = true,
        maxLines: Int = Int.MAX_VALUE,
        constraints: Constraints = Constraints(),
        layoutDirection: LayoutDirection = this.defaultLayoutDirection,
        density: Density = this.defaultDensity,
        fontFamilyResolver: FontFamily.Resolver = this.defaultFontFamilyResolver,
        skipCache: Boolean = false
    ): TextLayoutResult {
        return measure(
            text = AnnotatedString(text),
            style = style,
            overflow = overflow,
            softWrap = softWrap,
            maxLines = maxLines,
            constraints = constraints,
            layoutDirection = layoutDirection,
            density = density,
            fontFamilyResolver = fontFamilyResolver,
            skipCache = skipCache
        )
    }

    internal companion object {
        /**
         * Computes the visual position of the glyphs for painting the text.
         *
         * The text will layout with a width that's as close to its max intrinsic width as possible
         * while still being greater than or equal to `minWidth` and less than or equal to
         * `maxWidth`.
         */
        private fun layout(textLayoutInput: TextLayoutInput): TextLayoutResult =
            with(textLayoutInput) {
                val nonNullIntrinsics =
                    MultiParagraphIntrinsics(
                        annotatedString = text,
                        style = resolveDefaults(style, layoutDirection),
                        density = density,
                        fontFamilyResolver = fontFamilyResolver,
                        placeholders = placeholders
                    )

                val minWidth = constraints.minWidth
                val widthMatters = softWrap || overflow == TextOverflow.Ellipsis
                val maxWidth =
                    if (widthMatters && constraints.hasBoundedWidth) {
                        constraints.maxWidth
                    } else {
                        Constraints.Infinity
                    }

                // This is a fallback behavior because native text layout doesn't support multiple
                // ellipsis in one text layout.
                // When softWrap is turned off and overflow is ellipsis, it's expected that each
                // line
                // that exceeds maxWidth will be ellipsized.
                // For example,
                // input text:
                //     "AAAA\nAAAA"
                // maxWidth:
                //     3 * fontSize that only allow 3 characters to be displayed each line.
                // expected output:
                //     AA…
                //     AA…
                // Here we assume there won't be any '\n' character when softWrap is false. And make
                // maxLines 1 to implement the similar behavior.
                val overwriteMaxLines = !softWrap && overflow == TextOverflow.Ellipsis
                val finalMaxLines = if (overwriteMaxLines) 1 else maxLines

                // if minWidth == maxWidth the width is fixed.
                //    therefore we can pass that value to our paragraph and use it
                // if minWidth != maxWidth there is a range
                //    then we should check if the max intrinsic width is in this range to decide the
                //    width to be passed to Paragraph
                //        if max intrinsic width is between minWidth and maxWidth
                //           we can use it to layout
                //        else if max intrinsic width is greater than maxWidth, we can only use
                // maxWidth
                //        else if max intrinsic width is less than minWidth, we should use minWidth
                val width =
                    if (minWidth == maxWidth) {
                        maxWidth
                    } else {
                        nonNullIntrinsics.maxIntrinsicWidth.ceilToInt().coerceIn(minWidth, maxWidth)
                    }

                val multiParagraph =
                    MultiParagraph(
                        intrinsics = nonNullIntrinsics,
                        constraints =
                            Constraints.fitPrioritizingWidth(
                                minWidth = 0,
                                maxWidth = width,
                                minHeight = 0,
                                maxHeight = constraints.maxHeight
                            ),
                        // This is a fallback behavior for ellipsis. Native
                        maxLines = finalMaxLines,
                        ellipsis = overflow == TextOverflow.Ellipsis
                    )

                return TextLayoutResult(
                    layoutInput = textLayoutInput,
                    multiParagraph = multiParagraph,
                    size =
                        constraints.constrain(
                            IntSize(
                                ceil(multiParagraph.width).toInt(),
                                ceil(multiParagraph.height).toInt()
                            )
                        )
                )
            }
    }
}

/**
 * Keeps an LRU layout cache of TextLayoutInput, TextLayoutResult pairs. Any non-layout affecting
 * change in TextLayoutInput (color, brush, shadow, TextDecoration) is ignored by this cache.
 *
 * @param capacity Maximum size of LRU cache. Size unit is the number of [CacheTextLayoutInput] and
 *   [TextLayoutResult] pairs.
 * @throws IllegalArgumentException if capacity is not a positive integer.
 */
internal class TextLayoutCache(capacity: Int = DefaultCacheSize) {
    private val lruCache = LruCache<CacheTextLayoutInput, TextLayoutResult>(capacity)

    fun get(key: TextLayoutInput): TextLayoutResult? {
        val resultFromCache = lruCache.get(CacheTextLayoutInput(key)) ?: return null

        if (resultFromCache.multiParagraph.intrinsics.hasStaleResolvedFonts) {
            // one of the resolved fonts has updated, and this MeasuredText is no longer valid for
            // measure or display
            return null
        }

        return resultFromCache
    }

    fun put(key: TextLayoutInput, value: TextLayoutResult): TextLayoutResult? {
        return lruCache.put(CacheTextLayoutInput(key), value)
    }

    fun remove(key: TextLayoutInput): TextLayoutResult? {
        return lruCache.remove(CacheTextLayoutInput(key))
    }
}

/**
 * Provides custom hashCode and equals function that are only interested in layout affecting
 * attributes in TextLayoutInput. Used as a key in [TextLayoutCache].
 */
@Immutable
internal class CacheTextLayoutInput(val textLayoutInput: TextLayoutInput) {

    override fun hashCode(): Int =
        with(textLayoutInput) {
            var result = text.hashCode()
            result = 31 * result + style.hashCodeLayoutAffectingAttributes()
            result = 31 * result + placeholders.hashCode()
            result = 31 * result + maxLines
            result = 31 * result + softWrap.hashCode()
            result = 31 * result + overflow.hashCode()
            result = 31 * result + density.hashCode()
            result = 31 * result + layoutDirection.hashCode()
            result = 31 * result + fontFamilyResolver.hashCode()
            result = 31 * result + constraints.maxWidth.hashCode()
            result = 31 * result + constraints.maxHeight.hashCode()
            return result
        }

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (other !is CacheTextLayoutInput) return false

        with(textLayoutInput) {
            if (text != other.textLayoutInput.text) return false
            if (!style.hasSameLayoutAffectingAttributes(other.textLayoutInput.style)) return false
            if (placeholders != other.textLayoutInput.placeholders) return false
            if (maxLines != other.textLayoutInput.maxLines) return false
            if (softWrap != other.textLayoutInput.softWrap) return false
            if (overflow != other.textLayoutInput.overflow) return false
            if (density != other.textLayoutInput.density) return false
            if (layoutDirection != other.textLayoutInput.layoutDirection) return false
            if (fontFamilyResolver !== other.textLayoutInput.fontFamilyResolver) return false
            if (constraints.maxWidth != other.textLayoutInput.constraints.maxWidth) return false
            if (constraints.maxHeight != other.textLayoutInput.constraints.maxHeight) return false
        }

        return true
    }
}
