/*
 * 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.datasource

import androidx.wear.watchface.complications.data.ComplicationData
import androidx.wear.watchface.complications.data.NoDataComplicationData
import java.time.Instant

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

/**
 * A time interval, typically used to describe the validity period of a [TimelineEntry].
 *
 * @param start The [Instant] when this TimeInterval becomes valid
 * @param end The [Instant] when this TimeInterval becomes invalid, must be after [start]
 */
public class TimeInterval(
    public var start: Instant,
    public var end: Instant
) {
    init {
        require(start < end) { "start must be before end" }
    }

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

        other as TimeInterval

        if (start != other.start) return false
        if (end != other.end) return false

        return true
    }

    override fun hashCode(): Int {
        var result = start.hashCode()
        result = 31 * result + end.hashCode()
        return result
    }

    override fun toString(): String {
        return "TimeInterval(start=$start, end=$end)"
    }
}

/**
 * One piece of renderable content along with the time that it is valid for.
 *
 * @param validity [TimeInterval] describing the validity period for this timeline entry.
 * @param complicationData The renderable [ComplicationData].
 */
public class TimelineEntry(
    public var validity: TimeInterval,
    public var complicationData: ComplicationData
) {
    override fun equals(other: Any?): Boolean {
        if (this === other) return true
        if (javaClass != other?.javaClass) return false

        other as TimelineEntry

        if (validity != other.validity) return false
        if (complicationData != other.complicationData) return false

        return true
    }

    override fun hashCode(): Int {
        var result = validity.hashCode()
        result = 31 * result + complicationData.hashCode()
        return result
    }

    override fun toString(): String {
        return "TimelineEntry(validity=$validity, complicationData=$complicationData)"
    }
}

/**
 * A collection of TimelineEntry items.
 *
 * This allows a sequence of [ComplicationData] to be delivered to the watch face which can be
 * cached and updated automatically. E.g. today's weather forecast at various times or multiple
 * upcoming calendar events.
 *
 * In the case where the validity periods of TimelineEntry items overlap, the item with the
 * *shortest* validity period will be shown. If none are valid then the [defaultComplicationData]
 * will be shown.  This allows a complication datasource to show a "default", and override it at set
 * points without having to explicitly insert the default [ComplicationData] between the each
 * "override".
 *
 * The complication to render from a timeline is selected each time the watch face is rendered,
 * however the presence of a timeline does not trigger any extra frames to be rendered. Most watch
 * faces render at least once per minute at the top of the minute so complication updates should be
 * timely.
 *
 * Note older watch faces only support [defaultComplicationData], and v1.1 of wear-watchface is
 * required to support [timelineEntries].
 *
 * @param defaultComplicationData The default [ComplicationData] to be displayed
 * @param timelineEntries A collection of "overrides" to be displayed at certain times
 */
public class ComplicationDataTimeline(
    public val defaultComplicationData: ComplicationData,
    public val timelineEntries: Collection<TimelineEntry>
) {
    init {
        for (entry in timelineEntries) {
            val complicationData = entry.complicationData
            if (complicationData is NoDataComplicationData) {
                require(complicationData.placeholder == null ||
                    complicationData.placeholder!!.type == defaultComplicationData.type
                ) {
                    "TimelineEntry's placeholder types must match the defaultComplicationData. " +
                        "Found ${complicationData.placeholder!!.type} expected " +
                        "${defaultComplicationData.type}."
                }
            } else {
                require(
                    complicationData.type == defaultComplicationData.type
                ) {
                    "TimelineEntry's complicationData must have the same type as the " +
                        "defaultComplicationData or be NoDataComplicationData. Found " +
                        "${complicationData.type} expected ${defaultComplicationData.type}."
                }

                require(!complicationData.hasPlaceholderFields()) {
                    "Placeholder values may only be used in the context of " +
                        "NoDataComplicationData.placeholder ComplicationData."
                }
            }
        }
    }

    internal fun asWireComplicationData(): WireComplicationData {
        val wireTimelineEntries = timelineEntries.map { timelineEntry ->
            timelineEntry.complicationData.asWireComplicationData().apply {
                timelineStartEpochSecond = timelineEntry.validity.start.epochSecond
                timelineEndEpochSecond = timelineEntry.validity.end.epochSecond
            }
        }
        return defaultComplicationData.asWireComplicationData().apply {
            setTimelineEntryCollection(wireTimelineEntries)
        }
    }

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

        other as ComplicationDataTimeline

        if (defaultComplicationData != other.defaultComplicationData) return false
        if (timelineEntries != other.timelineEntries) return false

        return true
    }

    override fun hashCode(): Int {
        var result = defaultComplicationData.hashCode()
        result = 31 * result + timelineEntries.hashCode()
        return result
    }

    override fun toString(): String {
        return "ComplicationDataTimeline(defaultComplicationData=$defaultComplicationData, " +
            "timelineEntries=$timelineEntries)"
    }
}