/*
 * Copyright 2021 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.wear.watchface.complications.data

import android.app.PendingIntent
import android.graphics.drawable.Icon
import android.os.Build
import androidx.annotation.RestrictTo
import java.time.Instant

/** The wire format for [ComplicationData]. */
internal typealias WireComplicationData = android.support.wearable.complications.ComplicationData

/** The builder for [WireComplicationData]. */
internal typealias WireComplicationDataBuilder =
    android.support.wearable.complications.ComplicationData.Builder

/**
 * Base type for all different types of [ComplicationData] types.
 *
 * Please note to aid unit testing of ComplicationDataSourceServices, [equals], [hashCode] and
 * [toString] have been overridden for all the types of ComplicationData, however due to the
 * embedded [Icon] class we have to fall back to reference equality and hashing below API 28 and
 * also for the [Icon]s that don't use either a resource or a uri (these should be rare but they
 * can exist).
 */
public sealed class ComplicationData constructor(
    public val type: ComplicationType,
    public val tapAction: PendingIntent?,
    internal var cachedWireComplicationData: WireComplicationData?,
    /**
     * Describes when the complication should be displayed.
     *
     * Whether the complication is active and should be displayed at the given time should be
     * checked with [TimeRange.contains].
     */
    public val validTimeRange: TimeRange = TimeRange.ALWAYS
) {
    /**
     * [tapAction] which is a [PendingIntent] unfortunately can't be serialized. This property is
     * 'true' if tapAction has been lost due to serialization (typically because it has been cached
     * locally). When 'true' the watch face should render the complication differently (e.g. as
     * semi-transparent or grayed out) to signal to the user it can't be tapped. The system will
     * subsequently deliver an updated complication, with a tapAction where applicable.
     */
    @get:JvmName("isTapActionLostDueToSerialization")
    public var tapActionLostDueToSerialization: Boolean =
        cachedWireComplicationData?.tapActionLostDueToSerialization ?: false

    /**
     * Converts this value to [WireComplicationData] object used for serialization.
     *
     * This is only needed internally to convert to the underlying communication protocol.
     *
     * @hide
     */
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    public abstract fun asWireComplicationData(): WireComplicationData

    internal fun createWireComplicationDataBuilder(): WireComplicationDataBuilder =
        cachedWireComplicationData?.let {
            WireComplicationDataBuilder(it)
        } ?: WireComplicationDataBuilder(type.toWireComplicationType())
}

/**
 * Type that can be sent by any complication data source, regardless of the configured type, when
 * the complication data source has no data to be displayed. Watch faces may choose whether to
 * render this in some way or  leave the slot empty.
 */
public class NoDataComplicationData : ComplicationData(TYPE, null, null) {
    /** @hide */
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    override fun asWireComplicationData(): WireComplicationData = asPlainWireComplicationData(type)

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false
        return true
    }

    override fun hashCode(): Int {
        return javaClass.hashCode()
    }

    override fun toString(): String {
        return "NoDataComplicationData()"
    }

    /** @hide */
    public companion object {
        /** The [ComplicationType] corresponding to objects of this type. */
        @JvmField
        public val TYPE: ComplicationType = ComplicationType.NO_DATA
    }
}

/**
 * Type sent when the user has specified that an active complication should have no complication
 * data source, i.e. when the user has chosen "Empty" in the complication data source chooser.
 * Complication data sources cannot send data of this type.
 */
public class EmptyComplicationData : ComplicationData(TYPE, null, null) {
    /** @hide */
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    override fun asWireComplicationData(): WireComplicationData = asPlainWireComplicationData(type)

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false
        return true
    }

    override fun hashCode(): Int {
        return javaClass.hashCode()
    }

    override fun toString(): String {
        return "EmptyComplicationData()"
    }

    /** @hide */
    public companion object {
        /** The [ComplicationType] corresponding to objects of this type. */
        @JvmField
        public val TYPE: ComplicationType = ComplicationType.EMPTY
    }
}

/**
 * Type sent when a complication does not have a complication data source configured. The system
 * will send data of this type to watch faces when the user has not chosen a complication data
 * source for an active complication, and the watch face has not set a default complication data
 * source. Complication data sources cannot send data of this type.
 */
public class NotConfiguredComplicationData : ComplicationData(TYPE, null, null) {
    /** @hide */
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    override fun asWireComplicationData(): WireComplicationData = asPlainWireComplicationData(type)

    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false
        return true
    }

    override fun hashCode(): Int {
        return javaClass.hashCode()
    }

    override fun toString(): String {
        return "NotConfiguredComplicationData()"
    }

    /** @hide */
    public companion object {
        /** The [ComplicationType] corresponding to objects of this type. */
        @JvmField
        public val TYPE: ComplicationType = ComplicationType.NOT_CONFIGURED
    }
}

/**
 * Type used for complications where the primary piece of data is a short piece of text
 * (expected to be no more than seven characters in length). The text may be accompanied
 * by an icon or a title or both.
 *
 * If only one of icon and title is provided, it is expected that it will be displayed. If both
 * are provided, it is expected that at least one of these will be displayed.
 */
public class ShortTextComplicationData internal constructor(
    public val text: ComplicationText,
    public val title: ComplicationText?,
    public val monochromaticImage: MonochromaticImage?,
    public val contentDescription: ComplicationText?,
    tapAction: PendingIntent?,
    validTimeRange: TimeRange?,
    cachedWireComplicationData: WireComplicationData?
) : ComplicationData(
    TYPE, tapAction, cachedWireComplicationData, validTimeRange ?: TimeRange.ALWAYS
) {
    /**
     * Builder for [ShortTextComplicationData].
     *
     * You must at a minimum set the [text] and [contentDescription] fields.
     *
     * @param text The main localized [ComplicationText]. This must be less than 7 characters long
     * @param contentDescription Localized description for use by screen readers
     */
    public class Builder(
        private val text: ComplicationText,
        private var contentDescription: ComplicationText
    ) {
        private var tapAction: PendingIntent? = null
        private var validTimeRange: TimeRange? = null
        private var title: ComplicationText? = null
        private var monochromaticImage: MonochromaticImage? = null
        private var cachedWireComplicationData: WireComplicationData? = null

        /** Sets optional pending intent to be invoked when the complication is tapped. */
        public fun setTapAction(tapAction: PendingIntent?): Builder = apply {
            this.tapAction = tapAction
        }

        /** Sets optional time range during which the complication has to be shown. */
        @Suppress("MissingGetterMatchingBuilder") // b/174052810
        public fun setValidTimeRange(validTimeRange: TimeRange?): Builder = apply {
            this.validTimeRange = validTimeRange
        }

        /** Sets optional title associated with the complication data. */
        public fun setTitle(title: ComplicationText?): Builder = apply {
            this.title = title
        }

        /** Sets optional icon associated with the complication data. */
        public fun setMonochromaticImage(monochromaticImage: MonochromaticImage?): Builder = apply {
            this.monochromaticImage = monochromaticImage
        }

        internal fun setCachedWireComplicationData(
            cachedWireComplicationData: WireComplicationData?
        ): Builder = apply {
            this.cachedWireComplicationData = cachedWireComplicationData
        }

        /** Builds the [ShortTextComplicationData]. */
        public fun build(): ShortTextComplicationData =
            ShortTextComplicationData(
                text,
                title,
                monochromaticImage,
                contentDescription,
                tapAction,
                validTimeRange,
                cachedWireComplicationData
            )
    }

    /** @hide */
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    override fun asWireComplicationData(): WireComplicationData {
        cachedWireComplicationData?.let {
            return it
        }
        return createWireComplicationDataBuilder().apply {
            setShortText(text.toWireComplicationText())
            setShortTitle(title?.toWireComplicationText())
            setContentDescription(
                when (contentDescription) {
                    ComplicationText.EMPTY -> null
                    else -> contentDescription?.toWireComplicationText()
                }
            )
            monochromaticImage?.addToWireComplicationData(this)
            setTapAction(tapAction)
            setValidTimeRange(validTimeRange, this)
            setTapActionLostDueToSerialization(tapActionLostDueToSerialization)
        }.build().also { cachedWireComplicationData = it }
    }

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

        other as ShortTextComplicationData

        if (text != other.text) return false
        if (title != other.title) return false
        if (monochromaticImage != other.monochromaticImage) return false
        if (contentDescription != other.contentDescription) return false
        if (tapActionLostDueToSerialization != other.tapActionLostDueToSerialization) return false
        if (tapAction != other.tapAction) return false
        if (validTimeRange != other.validTimeRange) return false

        return true
    }

    override fun hashCode(): Int {
        var result = text.hashCode()
        result = 31 * result + (title?.hashCode() ?: 0)
        result = 31 * result + (monochromaticImage?.hashCode() ?: 0)
        result = 31 * result + (contentDescription?.hashCode() ?: 0)
        result = 31 * result + tapActionLostDueToSerialization.hashCode()
        result = 31 * result + (tapAction?.hashCode() ?: 0)
        result = 31 * result + validTimeRange.hashCode()
        return result
    }

    override fun toString(): String {
        return "ShortTextComplicationData(text=$text, title=$title, " +
            "monochromaticImage=$monochromaticImage, contentDescription=$contentDescription, " +
            "tapActionLostDueToSerialization=$tapActionLostDueToSerialization, " +
            "tapAction=$tapAction, validTimeRange=$validTimeRange)"
    }

    /** @hide */
    public companion object {
        /** The [ComplicationType] corresponding to objects of this type. */
        @JvmField
        public val TYPE: ComplicationType = ComplicationType.SHORT_TEXT

        /** The maximum length of [ShortTextComplicationData.text] in characters. */
        @JvmField
        public val MAX_TEXT_LENGTH = 7
    }
}

/**
 * Type used for complications where the primary piece of data is a piece of text. The text may
 * be accompanied by an icon and/or a title.
 *
 * The text is expected to always be displayed.
 *
 * The title, if provided, it is expected that this field will be displayed.
 *
 * If at least one of the icon and image is provided, one of these should be displayed.
 */
public class LongTextComplicationData internal constructor(
    public val text: ComplicationText,
    public val title: ComplicationText?,
    public val monochromaticImage: MonochromaticImage?,
    public val smallImage: SmallImage?,
    public val contentDescription: ComplicationText?,
    tapAction: PendingIntent?,
    validTimeRange: TimeRange?,
    cachedWireComplicationData: WireComplicationData?
) : ComplicationData(
    TYPE, tapAction, cachedWireComplicationData, validTimeRange ?: TimeRange.ALWAYS
) {
    /**
     * Builder for [LongTextComplicationData].
     *
     * You must at a minimum set the [text] and [contentDescription] fields.
     *
     * @param text Localized main [ComplicationText] to display within the complication. There
     * isn't an explicit character limit but text may be truncated if too long
     * @param contentDescription Localized description for use by screen readers
     */
    public class Builder(
        private val text: ComplicationText,
        private var contentDescription: ComplicationText
    ) {
        private var tapAction: PendingIntent? = null
        private var validTimeRange: TimeRange? = null
        private var title: ComplicationText? = null
        private var monochromaticImage: MonochromaticImage? = null
        private var smallImage: SmallImage? = null
        private var cachedWireComplicationData: WireComplicationData? = null

        /** Sets optional pending intent to be invoked when the complication is tapped. */
        public fun setTapAction(tapAction: PendingIntent?): Builder = apply {
            this.tapAction = tapAction
        }

        /** Sets optional time range during which the complication has to be shown. */
        @Suppress("MissingGetterMatchingBuilder") // b/174052810
        public fun setValidTimeRange(validTimeRange: TimeRange?): Builder = apply {
            this.validTimeRange = validTimeRange
        }

        /** Sets optional title associated with the complication data. */
        public fun setTitle(title: ComplicationText?): Builder = apply {
            this.title = title
        }

        /** Sets optional image associated with the complication data. */
        public fun setMonochromaticImage(icon: MonochromaticImage?): Builder = apply {
            this.monochromaticImage = icon
        }

        /** Sets optional image associated with the complication data. */
        public fun setSmallImage(smallImage: SmallImage?): Builder = apply {
            this.smallImage = smallImage
        }

        internal fun setCachedWireComplicationData(
            cachedWireComplicationData: WireComplicationData?
        ): Builder = apply {
            this.cachedWireComplicationData = cachedWireComplicationData
        }

        /** Builds the [LongTextComplicationData]. */
        public fun build(): LongTextComplicationData =
            LongTextComplicationData(
                text,
                title,
                monochromaticImage,
                smallImage,
                contentDescription,
                tapAction,
                validTimeRange,
                cachedWireComplicationData
            )
    }

    /** @hide */
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    override fun asWireComplicationData(): WireComplicationData {
        cachedWireComplicationData?.let {
            return it
        }
        return createWireComplicationDataBuilder().apply {
            setLongText(text.toWireComplicationText())
            setLongTitle(title?.toWireComplicationText())
            monochromaticImage?.addToWireComplicationData(this)
            smallImage?.addToWireComplicationData(this)
            setTapAction(tapAction)
            setContentDescription(
                when (contentDescription) {
                    ComplicationText.EMPTY -> null
                    else -> contentDescription?.toWireComplicationText()
                }
            )
            setValidTimeRange(validTimeRange, this)
            setTapActionLostDueToSerialization(tapActionLostDueToSerialization)
        }.build().also { cachedWireComplicationData = it }
    }

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

        other as LongTextComplicationData

        if (text != other.text) return false
        if (title != other.title) return false
        if (monochromaticImage != other.monochromaticImage) return false
        if (smallImage != other.smallImage) return false
        if (contentDescription != other.contentDescription) return false
        if (tapActionLostDueToSerialization != other.tapActionLostDueToSerialization) return false
        if (tapAction != other.tapAction) return false
        if (validTimeRange != other.validTimeRange) return false

        return true
    }

    override fun hashCode(): Int {
        var result = text.hashCode()
        result = 31 * result + (title?.hashCode() ?: 0)
        result = 31 * result + (monochromaticImage?.hashCode() ?: 0)
        result = 31 * result + (smallImage?.hashCode() ?: 0)
        result = 31 * result + (contentDescription?.hashCode() ?: 0)
        result = 31 * result + tapActionLostDueToSerialization.hashCode()
        result = 31 * result + (tapAction?.hashCode() ?: 0)
        result = 31 * result + validTimeRange.hashCode()
        return result
    }

    override fun toString(): String {
        return "LongTextComplicationData(text=$text, title=$title, " +
            "monochromaticImage=$monochromaticImage, smallImage=$smallImage, " +
            "contentDescription=$contentDescription), " +
            "tapActionLostDueToSerialization=$tapActionLostDueToSerialization, " +
            "tapAction=$tapAction, validTimeRange=$validTimeRange)"
    }

    /** @hide */
    public companion object {
        /** The [ComplicationType] corresponding to objects of this type. */
        @JvmField
        public val TYPE: ComplicationType = ComplicationType.LONG_TEXT
    }
}

/**
 * Type used for complications including a numerical value within a range, such as a percentage.
 * The value may be accompanied by an icon and/or short text and title.
 *
 * The [value], [min], and [max] fields are required for this type and the value within the
 * range is expected to always be displayed.
 *
 * The icon, title, and text fields are optional and the watch face may choose which of these
 * fields to display, if any.
 */
public class RangedValueComplicationData internal constructor(
    public val value: Float,
    public val min: Float,
    public val max: Float,
    public val monochromaticImage: MonochromaticImage?,
    public val title: ComplicationText?,
    public val text: ComplicationText?,
    public val contentDescription: ComplicationText?,
    tapAction: PendingIntent?,
    validTimeRange: TimeRange?,
    cachedWireComplicationData: WireComplicationData?
) : ComplicationData(
    TYPE, tapAction, cachedWireComplicationData, validTimeRange ?: TimeRange.ALWAYS
) {
    /**
     * Builder for [RangedValueComplicationData].
     *
     * You must at a minimum set the [value], [min], [max] and [contentDescription] fields.
     *
     * @param value The value of the ranged complication which should be in the range
     * [[min]] .. [[max]]
     * @param min The minimum value
     * @param max The maximum value
     * @param contentDescription Localized description for use by screen readers
     */
    public class Builder(
        private val value: Float,
        private val min: Float,
        private val max: Float,
        private var contentDescription: ComplicationText
    ) {
        private var tapAction: PendingIntent? = null
        private var validTimeRange: TimeRange? = null
        private var monochromaticImage: MonochromaticImage? = null
        private var title: ComplicationText? = null
        private var text: ComplicationText? = null
        private var cachedWireComplicationData: WireComplicationData? = null

        /** Sets optional pending intent to be invoked when the complication is tapped. */
        public fun setTapAction(tapAction: PendingIntent?): Builder = apply {
            this.tapAction = tapAction
        }

        /** Sets optional time range during which the complication has to be shown. */
        @Suppress("MissingGetterMatchingBuilder") // b/174052810
        public fun setValidTimeRange(validTimeRange: TimeRange?): Builder = apply {
            this.validTimeRange = validTimeRange
        }

        /** Sets optional icon associated with the complication data. */
        public fun setMonochromaticImage(monochromaticImage: MonochromaticImage?): Builder = apply {
            this.monochromaticImage = monochromaticImage
        }

        /** Sets optional title associated with the complication data. */
        public fun setTitle(title: ComplicationText?): Builder = apply {
            this.title = title
        }

        /** Sets optional title associated with the complication data. */
        public fun setText(text: ComplicationText?): Builder = apply {
            this.text = text
        }

        internal fun setCachedWireComplicationData(
            cachedWireComplicationData: WireComplicationData?
        ): Builder = apply {
            this.cachedWireComplicationData = cachedWireComplicationData
        }

        /** Builds the [RangedValueComplicationData]. */
        public fun build(): RangedValueComplicationData =
            RangedValueComplicationData(
                value,
                min,
                max,
                monochromaticImage,
                title,
                text,
                contentDescription,
                tapAction,
                validTimeRange,
                cachedWireComplicationData
            )
    }

    /** @hide */
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    public override fun asWireComplicationData(): WireComplicationData {
        cachedWireComplicationData?.let {
            return it
        }
        return createWireComplicationDataBuilder().apply {
            setRangedValue(value)
            setRangedMinValue(min)
            setRangedMaxValue(max)
            monochromaticImage?.addToWireComplicationData(this)
            setShortText(text?.toWireComplicationText())
            setShortTitle(title?.toWireComplicationText())
            setTapAction(tapAction)
            setContentDescription(
                when (contentDescription) {
                    ComplicationText.EMPTY -> null
                    else -> contentDescription?.toWireComplicationText()
                }
            )
            setValidTimeRange(validTimeRange, this)
            setTapActionLostDueToSerialization(tapActionLostDueToSerialization)
        }.build().also { cachedWireComplicationData = it }
    }

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

        other as RangedValueComplicationData

        if (value != other.value) return false
        if (min != other.min) return false
        if (max != other.max) return false
        if (monochromaticImage != other.monochromaticImage) return false
        if (title != other.title) return false
        if (text != other.text) return false
        if (contentDescription != other.contentDescription) return false
        if (tapActionLostDueToSerialization != other.tapActionLostDueToSerialization) return false
        if (tapAction != other.tapAction) return false
        if (validTimeRange != other.validTimeRange) return false

        return true
    }

    override fun hashCode(): Int {
        var result = value.hashCode()
        result = 31 * result + min.hashCode()
        result = 31 * result + max.hashCode()
        result = 31 * result + (monochromaticImage?.hashCode() ?: 0)
        result = 31 * result + (title?.hashCode() ?: 0)
        result = 31 * result + (text?.hashCode() ?: 0)
        result = 31 * result + (contentDescription?.hashCode() ?: 0)
        result = 31 * result + tapActionLostDueToSerialization.hashCode()
        result = 31 * result + (tapAction?.hashCode() ?: 0)
        result = 31 * result + validTimeRange.hashCode()
        return result
    }

    override fun toString(): String {
        return "RangedValueComplicationData(value=$value, min=$min, max=$max, " +
            "monochromaticImage=$monochromaticImage, title=$title, text=$text, " +
            "contentDescription=$contentDescription), " +
            "tapActionLostDueToSerialization=$tapActionLostDueToSerialization, " +
            "tapAction=$tapAction, validTimeRange=$validTimeRange)"
    }

    /** @hide */
    public companion object {
        /** The [ComplicationType] corresponding to objects of this type. */
        @JvmField
        public val TYPE: ComplicationType = ComplicationType.RANGED_VALUE
    }
}

/**
 * Type used for complications which consist only of a [MonochromaticImage].
 *
 * The image is expected to always be displayed.
 *
 * The contentDescription field and is used to describe what data the icon represents. If the
 * icon is purely stylistic, and does not convey any information to the user, then provide an
 * empty content description. If no content description is provided, a generic content
 * description will be used instead.
 */
public class MonochromaticImageComplicationData internal constructor(
    public val monochromaticImage: MonochromaticImage,
    public val contentDescription: ComplicationText?,
    tapAction: PendingIntent?,
    validTimeRange: TimeRange?,
    cachedWireComplicationData: WireComplicationData?
) : ComplicationData(
    TYPE, tapAction, cachedWireComplicationData, validTimeRange ?: TimeRange.ALWAYS
) {
    /**
     * Builder for [MonochromaticImageComplicationData].
     *
     * You must at a minimum set the [monochromaticImage] and [contentDescription] fields.
     *
     * @param monochromaticImage The [MonochromaticImage] to be displayed
     * @param contentDescription Localized description for use by screen readers
     */
    public class Builder(
        private val monochromaticImage: MonochromaticImage,
        private val contentDescription: ComplicationText
    ) {
        private var tapAction: PendingIntent? = null
        private var validTimeRange: TimeRange? = null
        private var cachedWireComplicationData: WireComplicationData? = null

        /** Sets optional pending intent to be invoked when the complication is tapped. */
        public fun setTapAction(tapAction: PendingIntent?): Builder = apply {
            this.tapAction = tapAction
        }

        /** Sets optional time range during which the complication has to be shown. */
        @Suppress("MissingGetterMatchingBuilder") // b/174052810
        public fun setValidTimeRange(validTimeRange: TimeRange?): Builder = apply {
            this.validTimeRange = validTimeRange
        }

        internal fun setCachedWireComplicationData(
            cachedWireComplicationData: WireComplicationData?
        ): Builder = apply {
            this.cachedWireComplicationData = cachedWireComplicationData
        }

        /** Builds the [MonochromaticImageComplicationData]. */
        public fun build(): MonochromaticImageComplicationData =
            MonochromaticImageComplicationData(
                monochromaticImage,
                contentDescription,
                tapAction,
                validTimeRange,
                cachedWireComplicationData
            )
    }

    /** @hide */
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    override fun asWireComplicationData(): WireComplicationData {
        cachedWireComplicationData?.let {
            return it
        }
        return createWireComplicationDataBuilder().apply {
            monochromaticImage.addToWireComplicationData(this)
            setContentDescription(
                when (contentDescription) {
                    ComplicationText.EMPTY -> null
                    else -> contentDescription?.toWireComplicationText()
                }
            )
            setTapAction(tapAction)
            setValidTimeRange(validTimeRange, this)
            setTapActionLostDueToSerialization(tapActionLostDueToSerialization)
        }.build().also { cachedWireComplicationData = it }
    }

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

        other as MonochromaticImageComplicationData

        if (monochromaticImage != other.monochromaticImage) return false
        if (contentDescription != other.contentDescription) return false
        if (tapActionLostDueToSerialization != other.tapActionLostDueToSerialization) return false
        if (tapAction != other.tapAction) return false
        if (validTimeRange != other.validTimeRange) return false

        return true
    }

    override fun hashCode(): Int {
        var result = monochromaticImage.hashCode()
        result = 31 * result + (contentDescription?.hashCode() ?: 0)
        result = 31 * result + tapActionLostDueToSerialization.hashCode()
        result = 31 * result + (tapAction?.hashCode() ?: 0)
        result = 31 * result + validTimeRange.hashCode()
        return result
    }

    override fun toString(): String {
        return "MonochromaticImageComplicationData(monochromaticImage=$monochromaticImage, " +
            "contentDescription=$contentDescription), " +
            "tapActionLostDueToSerialization=$tapActionLostDueToSerialization, " +
            "tapAction=$tapAction, validTimeRange=$validTimeRange)"
    }

    /** @hide */
    public companion object {
        /** The [ComplicationType] corresponding to objects of this type. */
        @JvmField
        public val TYPE: ComplicationType = ComplicationType.MONOCHROMATIC_IMAGE
    }
}

/**
 * Type used for complications which consist only of a [SmallImage].
 *
 * The image is expected to always be displayed.
 *
 * The [contentDescription] field and is used to describe what data the icon represents. If the
 * icon is purely stylistic, and does not convey any information to the user, then provide an
 * empty content description. If no content description is provided, a generic content
 * description will be used instead.
 */
public class SmallImageComplicationData internal constructor(
    public val smallImage: SmallImage,
    public val contentDescription: ComplicationText?,
    tapAction: PendingIntent?,
    validTimeRange: TimeRange?,
    cachedWireComplicationData: WireComplicationData?
) : ComplicationData(
    TYPE, tapAction, cachedWireComplicationData, validTimeRange ?: TimeRange.ALWAYS
) {
    /**
     * Builder for [SmallImageComplicationData].
     *
     * You must at a minimum set the [smallImage] and [contentDescription] fields.
     *
     * @param smallImage The [SmallImage] to be displayed
     * @param contentDescription Localized description for use by screen readers
     */
    public class Builder(
        private val smallImage: SmallImage,
        private val contentDescription: ComplicationText
    ) {
        private var tapAction: PendingIntent? = null
        private var validTimeRange: TimeRange? = null
        private var cachedWireComplicationData: WireComplicationData? = null

        /** Sets optional pending intent to be invoked when the complication is tapped. */
        public fun setTapAction(tapAction: PendingIntent?): Builder = apply {
            this.tapAction = tapAction
        }

        /** Sets optional time range during which the complication has to be shown. */
        @Suppress("MissingGetterMatchingBuilder") // b/174052810
        public fun setValidTimeRange(validTimeRange: TimeRange?): Builder = apply {
            this.validTimeRange = validTimeRange
        }

        internal fun setCachedWireComplicationData(
            cachedWireComplicationData: WireComplicationData?
        ): Builder = apply {
            this.cachedWireComplicationData = cachedWireComplicationData
        }

        /** Builds the [MonochromaticImageComplicationData]. */
        public fun build(): SmallImageComplicationData =
            SmallImageComplicationData(
                smallImage,
                contentDescription,
                tapAction,
                validTimeRange,
                cachedWireComplicationData
            )
    }

    /** @hide */
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    override fun asWireComplicationData(): WireComplicationData {
        cachedWireComplicationData?.let {
            return it
        }
        return createWireComplicationDataBuilder().apply {
            smallImage.addToWireComplicationData(this)
            setContentDescription(
                when (contentDescription) {
                    ComplicationText.EMPTY -> null
                    else -> contentDescription?.toWireComplicationText()
                }
            )
            setTapAction(tapAction)
            setValidTimeRange(validTimeRange, this)
            setTapActionLostDueToSerialization(tapActionLostDueToSerialization)
        }.build().also { cachedWireComplicationData = it }
    }

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

        other as SmallImageComplicationData

        if (smallImage != other.smallImage) return false
        if (contentDescription != other.contentDescription) return false
        if (tapActionLostDueToSerialization != other.tapActionLostDueToSerialization) return false
        if (tapAction != other.tapAction) return false
        if (validTimeRange != other.validTimeRange) return false

        return true
    }

    override fun hashCode(): Int {
        var result = smallImage.hashCode()
        result = 31 * result + (contentDescription?.hashCode() ?: 0)
        result = 31 * result + tapActionLostDueToSerialization.hashCode()
        result = 31 * result + (tapAction?.hashCode() ?: 0)
        result = 31 * result + validTimeRange.hashCode()
        return result
    }

    override fun toString(): String {
        return "SmallImageComplicationData(smallImage=$smallImage, " +
            "contentDescription=$contentDescription), " +
            "tapActionLostDueToSerialization=$tapActionLostDueToSerialization, " +
            "tapAction=$tapAction, validTimeRange=$validTimeRange)"
    }

    /** @hide */
    public companion object {
        /** The [ComplicationType] corresponding to objects of this type. */
        @JvmField
        public val TYPE: ComplicationType = ComplicationType.SMALL_IMAGE
    }
}

/**
 * Type used for complications which consist only of an image that is expected to fill a large part
 * of the watch face, large enough to be shown as either a background or as part of a high
 * resolution complication.
 *
 * The image is expected to always be displayed. The image may be shown as the background, any
 * other part of the watch face or within a complication. The image is large enough to be cover
 * the entire screen. The image may be cropped to fit the watch face or complication.
 *
 * The [contentDescription] field and is used to describe what data the icon represents. If the
 * icon is purely stylistic, and does not convey any information to the user, then provide an
 * empty content description. If no content description is provided, a generic content
 * description will be used instead.
 */
public class PhotoImageComplicationData internal constructor(
    public val photoImage: Icon,
    public val contentDescription: ComplicationText?,
    tapAction: PendingIntent?,
    validTimeRange: TimeRange?,
    cachedWireComplicationData: WireComplicationData?
) : ComplicationData(
    TYPE, tapAction, cachedWireComplicationData, validTimeRange ?: TimeRange.ALWAYS
) {
    /**
     * Builder for [PhotoImageComplicationData].
     *
     * You must at a minimum set the [photoImage] and [contentDescription] fields.
     *
     * @param photoImage The [Icon] to be displayed
     * @param contentDescription Localized description for use by screen readers
     */
    public class Builder(
        private val photoImage: Icon,
        private val contentDescription: ComplicationText
    ) {
        private var tapAction: PendingIntent? = null
        private var validTimeRange: TimeRange? = null
        private var cachedWireComplicationData: WireComplicationData? = null

        /** Sets optional pending intent to be invoked when the complication is tapped. */
        @SuppressWarnings("MissingGetterMatchingBuilder") // See http://b/174052810
        public fun setTapAction(tapAction: PendingIntent?): Builder = apply {
            this.tapAction = tapAction
        }

        /** Sets optional time range during which the complication has to be shown. */
        @SuppressWarnings("MissingGetterMatchingBuilder") // See http://b/174052810
        public fun setValidTimeRange(validTimeRange: TimeRange?): Builder = apply {
            this.validTimeRange = validTimeRange
        }

        internal fun setCachedWireComplicationData(
            cachedWireComplicationData: WireComplicationData?
        ): Builder = apply {
            this.cachedWireComplicationData = cachedWireComplicationData
        }

        /** Builds the [PhotoImageComplicationData]. */
        public fun build(): PhotoImageComplicationData =
            PhotoImageComplicationData(
                photoImage,
                contentDescription,
                tapAction,
                validTimeRange,
                cachedWireComplicationData
            )
    }

    /** @hide */
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    override fun asWireComplicationData(): WireComplicationData {
        cachedWireComplicationData?.let {
            return it
        }
        return createWireComplicationDataBuilder().apply {
            setLargeImage(photoImage)
            setContentDescription(
                when (contentDescription) {
                    ComplicationText.EMPTY -> null
                    else -> contentDescription?.toWireComplicationText()
                }
            )
            setValidTimeRange(validTimeRange, this)
        }.build().also { cachedWireComplicationData = it }
    }

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

        other as PhotoImageComplicationData

        if (!if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                IconHelperP.equals(photoImage, other.photoImage)
            } else {
                IconHelperBeforeP.equals(photoImage, other.photoImage)
            }
        ) return false

        if (contentDescription != other.contentDescription) return false
        if (tapActionLostDueToSerialization != other.tapActionLostDueToSerialization) return false
        if (tapAction != other.tapAction) return false
        if (validTimeRange != other.validTimeRange) return false

        return true
    }

    override fun hashCode(): Int {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
            var result = IconHelperP.hashCode(photoImage)
            result = 31 * result + (contentDescription?.hashCode() ?: 0)
            result = 31 * result + tapActionLostDueToSerialization.hashCode()
            result = 31 * result + (tapAction?.hashCode() ?: 0)
            result = 31 * result + validTimeRange.hashCode()
            result
        } else {
            var result = IconHelperBeforeP.hashCode(photoImage)
            result = 31 * result + (contentDescription?.hashCode() ?: 0)
            result = 31 * result + tapActionLostDueToSerialization.hashCode()
            result = 31 * result + (tapAction?.hashCode() ?: 0)
            result = 31 * result + validTimeRange.hashCode()
            result
        }
    }

    override fun toString(): String {
        return "PhotoImageComplicationData(photoImage=$photoImage, " +
            "contentDescription=$contentDescription), " +
            "tapActionLostDueToSerialization=$tapActionLostDueToSerialization, " +
            "tapAction=$tapAction, validTimeRange=$validTimeRange)"
    }

    /** @hide */
    public companion object {
        /** The [ComplicationType] corresponding to objects of this type. */
        @JvmField
        public val TYPE: ComplicationType = ComplicationType.PHOTO_IMAGE
    }
}

/**
 * Type sent by the system when the watch face does not have permission to receive complication
 * data.
 *
 * The text, title, and icon may be displayed by watch faces, but this is not required.
 *
 * It is recommended that, where possible, tapping on the complication when in this state
 * should trigger a permission request. Note this is done by
 * [androidx.wear.watchface.ComplicationSlotsManager] for androidx watch faces.
 */
public class NoPermissionComplicationData internal constructor(
    public val text: ComplicationText?,
    public val title: ComplicationText?,
    public val monochromaticImage: MonochromaticImage?,
    cachedWireComplicationData: WireComplicationData?
) : ComplicationData(TYPE, null, cachedWireComplicationData) {
    /**
     * Builder for [NoPermissionComplicationData].
     *
     * You must at a minimum set the [tapAction].
     */
    public class Builder {
        private var text: ComplicationText? = null
        private var title: ComplicationText? = null
        private var monochromaticImage: MonochromaticImage? = null
        private var cachedWireComplicationData: WireComplicationData? = null

        /** Sets optional text associated with the complication data. */
        public fun setText(text: ComplicationText?): Builder = apply {
            this.text = text
        }

        /** Sets optional title associated with the complication data. */
        public fun setTitle(title: ComplicationText?): Builder = apply {
            this.title = title
        }

        /** Sets optional icon associated with the complication data. */
        public fun setMonochromaticImage(monochromaticImage: MonochromaticImage?): Builder = apply {
            this.monochromaticImage = monochromaticImage
        }

        internal fun setCachedWireComplicationData(
            cachedWireComplicationData: WireComplicationData?
        ): Builder = apply {
            this.cachedWireComplicationData = cachedWireComplicationData
        }

        /** Builds the [NoPermissionComplicationData]. */
        public fun build(): NoPermissionComplicationData =
            NoPermissionComplicationData(
                text,
                title,
                monochromaticImage,
                cachedWireComplicationData
            )
    }

    /** @hide */
    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    override fun asWireComplicationData(): WireComplicationData {
        cachedWireComplicationData?.let {
            return it
        }
        return createWireComplicationDataBuilder().apply {
            setShortText(text?.toWireComplicationText())
            setShortTitle(title?.toWireComplicationText())
            monochromaticImage?.addToWireComplicationData(this)
        }.build().also { cachedWireComplicationData = it }
    }

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

        other as NoPermissionComplicationData

        if (text != other.text) return false
        if (title != other.title) return false
        if (monochromaticImage != other.monochromaticImage) return false
        if (tapActionLostDueToSerialization != other.tapActionLostDueToSerialization) return false
        if (tapAction != other.tapAction) return false
        if (validTimeRange != other.validTimeRange) return false

        return true
    }

    override fun hashCode(): Int {
        var result = text?.hashCode() ?: 0
        result = 31 * result + (title?.hashCode() ?: 0)
        result = 31 * result + (monochromaticImage?.hashCode() ?: 0)
        result = 31 * result + tapActionLostDueToSerialization.hashCode()
        result = 31 * result + (tapAction?.hashCode() ?: 0)
        result = 31 * result + validTimeRange.hashCode()
        return result
    }

    override fun toString(): String {
        return "NoPermissionComplicationData(text=$text, title=$title, " +
            "monochromaticImage=$monochromaticImage, tapActionLostDueToSerialization=" +
            "$tapActionLostDueToSerialization, tapAction=$tapAction, " +
            "validTimeRange=$validTimeRange)"
    }

    /** @hide */
    public companion object {
        /** The [ComplicationType] corresponding to objects of this type. */
        @JvmField
        public val TYPE: ComplicationType = ComplicationType.NO_PERMISSION
    }
}

/**
 * @hide
 */
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public fun WireComplicationData.toApiComplicationData(): ComplicationData {
    val wireComplicationData = this
    return when (type) {
        NoDataComplicationData.TYPE.toWireComplicationType() -> NoDataComplicationData()

        EmptyComplicationData.TYPE.toWireComplicationType() -> EmptyComplicationData()

        NotConfiguredComplicationData.TYPE.toWireComplicationType() ->
            NotConfiguredComplicationData()

        ShortTextComplicationData.TYPE.toWireComplicationType() ->
            ShortTextComplicationData.Builder(
                shortText!!.toApiComplicationText(),
                contentDescription?.toApiComplicationText() ?: ComplicationText.EMPTY
            ).apply {
                setTapAction(tapAction)
                setValidTimeRange(parseTimeRange())
                setTitle(shortTitle?.toApiComplicationText())
                setMonochromaticImage(parseIcon())
                setCachedWireComplicationData(wireComplicationData)
            }.build()

        LongTextComplicationData.TYPE.toWireComplicationType() ->
            LongTextComplicationData.Builder(
                longText!!.toApiComplicationText(),
                contentDescription?.toApiComplicationText() ?: ComplicationText.EMPTY
            ).apply {
                setTapAction(tapAction)
                setValidTimeRange(parseTimeRange())
                setTitle(longTitle?.toApiComplicationText())
                setMonochromaticImage(parseIcon())
                setSmallImage(parseSmallImage())
                setCachedWireComplicationData(wireComplicationData)
            }.build()

        RangedValueComplicationData.TYPE.toWireComplicationType() ->
            RangedValueComplicationData.Builder(
                value = rangedValue, min = rangedMinValue,
                max = rangedMaxValue,
                contentDescription = contentDescription?.toApiComplicationText()
                    ?: ComplicationText.EMPTY
            ).apply {
                setTapAction(tapAction)
                setValidTimeRange(parseTimeRange())
                setMonochromaticImage(parseIcon())
                setTitle(shortTitle?.toApiComplicationText())
                setText(shortText?.toApiComplicationText())
                setCachedWireComplicationData(wireComplicationData)
            }.build()

        MonochromaticImageComplicationData.TYPE.toWireComplicationType() ->
            MonochromaticImageComplicationData.Builder(
                parseIcon()!!,
                contentDescription?.toApiComplicationText() ?: ComplicationText.EMPTY
            ).apply {
                setTapAction(tapAction)
                setValidTimeRange(parseTimeRange())
                setCachedWireComplicationData(wireComplicationData)
            }.build()

        SmallImageComplicationData.TYPE.toWireComplicationType() ->
            SmallImageComplicationData.Builder(
                parseSmallImage()!!,
                contentDescription?.toApiComplicationText() ?: ComplicationText.EMPTY
            ).apply {
                setTapAction(tapAction)
                setValidTimeRange(parseTimeRange())
                setCachedWireComplicationData(wireComplicationData)
            }.build()

        PhotoImageComplicationData.TYPE.toWireComplicationType() ->
            PhotoImageComplicationData.Builder(
                largeImage!!,
                contentDescription?.toApiComplicationText() ?: ComplicationText.EMPTY
            ).apply {
                setValidTimeRange(parseTimeRange())
                setCachedWireComplicationData(wireComplicationData)
            }.build()

        NoPermissionComplicationData.TYPE.toWireComplicationType() ->
            NoPermissionComplicationData.Builder().apply {
                setMonochromaticImage(parseIcon())
                setTitle(shortTitle?.toApiComplicationText())
                setText(shortText?.toApiComplicationText())
                setCachedWireComplicationData(wireComplicationData)
            }.build()

        else -> NoDataComplicationData()
    }
}

private fun WireComplicationData.parseTimeRange() =
    if ((startDateTimeMillis == 0L) and (endDateTimeMillis == Long.MAX_VALUE)) {
        null
    } else {
        TimeRange(
            Instant.ofEpochMilli(startDateTimeMillis),
            Instant.ofEpochMilli(endDateTimeMillis)
        )
    }

private fun WireComplicationData.parseIcon() =
    icon?.let {
        MonochromaticImage.Builder(it).apply {
            setAmbientImage(burnInProtectionIcon)
        }.build()
    }

private fun WireComplicationData.parseSmallImage() =
    smallImage?.let {
        val imageStyle = when (smallImageStyle) {
            WireComplicationData.IMAGE_STYLE_ICON -> SmallImageType.ICON
            WireComplicationData.IMAGE_STYLE_PHOTO -> SmallImageType.PHOTO
            else -> SmallImageType.PHOTO
        }
        SmallImage.Builder(it, imageStyle).apply {
            setAmbientImage(burnInProtectionSmallImage)
        }.build()
    }

/** Some of the types, do not have any fields. This method provides a shorthard for that case. */
internal fun asPlainWireComplicationData(type: ComplicationType) =
    WireComplicationDataBuilder(type.toWireComplicationType()).build()

internal fun setValidTimeRange(validTimeRange: TimeRange?, data: WireComplicationDataBuilder) {
    validTimeRange?.let {
        if (it.startDateTimeMillis > Instant.MIN) {
            data.setStartDateTimeMillis(it.startDateTimeMillis.toEpochMilli())
        }
        if (it.endDateTimeMillis != Instant.MAX) {
            data.setEndDateTimeMillis(it.endDateTimeMillis.toEpochMilli())
        }
    }
}
