/*
 * Copyright 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package androidx.camera.camera2.pipe

import androidx.annotation.RestrictTo
import androidx.camera.camera2.pipe.graph.GraphListener
import kotlinx.coroutines.Deferred
import kotlinx.coroutines.flow.Flow

/** This is used to uniquely identify a specific backend implementation. */
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
@JvmInline
value class CameraBackendId(val value: String)

/**
 * A CameraStatusMonitors monitors the status of the cameras, and emits updates when the status of
 * cameras changes, for instance when the camera access priorities have changed or when a particular
 * camera has become available.
 */
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
interface CameraStatusMonitor {
    val cameraStatus: Flow<CameraStatus>

    abstract class CameraStatus internal constructor() {
        object CameraPrioritiesChanged : CameraStatus() {
            override fun toString(): String = "CameraPrioritiesChanged"
        }

        class CameraAvailable(val cameraId: CameraId) : CameraStatus() {
            override fun toString(): String = "CameraAvailable(camera=$cameraId"
        }
    }
}

/**
 * A CameraBackend is used by [CameraPipe] to abstract out the lifecycle, state, and interactions
 * with a set of camera devices in a standard way.
 *
 * Each [CameraBackend] is responsible for interacting with all of the individual cameras that are
 * available through this backend. Since cameras often have complicated lifecycles and expensive
 * interactions, this object serves as a low level facade that is used to manage access _across_ all
 * cameras exposed by this backend.
 *
 * The lifecycle of an individual camera is managed by [CameraController]s, which may be created via
 * [CameraBackend.createCameraController].
 */
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
interface CameraBackend {
    val id: CameraBackendId

    /**
     * A flow of camera statuses that provide camera status updates such as when the camera access
     * priorities have changed, or a certain camera has become available.
     */
    val cameraStatus: Flow<CameraStatusMonitor.CameraStatus>

    /**
     * Read out a list of _openable_ [CameraId]s for this backend. The backend may be able to report
     * Metadata for non-openable cameras. However, these cameras should not appear the list of
     * cameras returned by [getCameraIds].
     */
    suspend fun getCameraIds(): List<CameraId>? = awaitCameraIds()

    /** Thread-blocking version of [getCameraIds] for compatibility. */
    fun awaitCameraIds(): List<CameraId>?

    /**
     * Read out a set of [CameraId] sets that can be operated concurrently. When multiple cameras
     * are open, the number of configurable streams, as well as their sizes, might be considerably
     * limited.
     */
    suspend fun getConcurrentCameraIds(): Set<Set<CameraId>>? = awaitConcurrentCameraIds()

    /** Thread-blocking version of [getConcurrentCameraIds] for compatibility. */
    fun awaitConcurrentCameraIds(): Set<Set<CameraId>>?

    /**
     * Retrieve [CameraMetadata] for this backend. Backends may cache the results of these calls.
     *
     * This call should should always succeed if the [CameraId] is in the list of ids returned by
     * [getCameraIds]. For some backends, it may be possible to retrieve metadata for cameras that
     * cannot be opened directly.
     */
    suspend fun getCameraMetadata(cameraId: CameraId): CameraMetadata? =
        awaitCameraMetadata(cameraId)

    /** Thread-blocking version of [getCameraMetadata] for compatibility. */
    fun awaitCameraMetadata(cameraId: CameraId): CameraMetadata?

    /**
     * Stops all active [CameraController]s, which may disconnect any cached camera connection(s).
     * This may be called on the main thread, and any long running background operations should be
     * executed in the background. Once all connections are fully closed, the returned [Deferred]
     * should be completed.
     *
     * Subsequent [CameraController]s may still be created after invoking [disconnectAllAsync], and
     * existing [CameraController]s may attempt to restart.
     */
    fun disconnectAllAsync(): Deferred<Unit>

    /**
     * Shutdown this backend, closing active [CameraController]s, and clearing any cached resources.
     *
     * This method should be used carefully, as it can cause expensive reloading and re-querying of
     * camera lists, metadata, and state. Once a backend instance has been shut down it should not
     * be reused, and a new instance must be recreated.
     */
    fun shutdownAsync(): Deferred<Unit>

    /**
     * Creates a new [CameraController] instance that can be used to initialize and interact with a
     * specific Camera that is available from this CameraBackend. Creating a [CameraController]
     * should _not_ begin opening or interacting with the Camera until [CameraController.start] is
     * called.
     */
    fun createCameraController(
        cameraContext: CameraContext,
        graphConfig: CameraGraph.Config,
        graphListener: GraphListener,
        streamGraph: StreamGraph
    ): CameraController

    /** Connects and starts the underlying camera */
    fun prewarm(cameraId: CameraId)

    /** Disconnects the underlying camera. */
    fun disconnect(cameraId: CameraId)

    /**
     * Disconnects the underlying camera. Once the connection is closed, the returned [Deferred]
     * should be completed.
     */
    fun disconnectAsync(cameraId: CameraId): Deferred<Unit>

    /** Disconnects all active Cameras. */
    fun disconnectAll()
}

/**
 * Factory for creating a new [CameraBackend].
 *
 * [CameraBackend] instances should not be cached by the factory instance, as the lifecycle of
 * returned instances is managed by [CameraPipe] unless the application asks [CameraPipe] to close
 * and release previously created [CameraBackend]s.
 */
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
fun interface CameraBackendFactory {
    /** Create a new [CameraBackend] instance based on the provided [CameraContext]. */
    fun create(cameraContext: CameraContext): CameraBackend
}

/**
 * Api for requesting and interacting with [CameraBackend] that are available in the current
 * [CameraPipe] instance.
 */
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
interface CameraBackends {
    /**
     * This provides access to the default [CameraBackend]. Accessing this property will create the
     * backend if it is not already created.
     */
    val default: CameraBackend

    /**
     * This provides a list of all available [CameraBackend] instances, including the default one.
     * Accessing this set will not create or initialize [CameraBackend] instances.
     */
    val allIds: Set<CameraBackendId>

    /**
     * This provides a list of [CameraBackend] instances that have been loaded, including the
     * default camera backend. Accessing this set will not create or initialize [CameraBackend]
     * instances.
     */
    val activeIds: Set<CameraBackendId>

    /**
     * Get a previously created [CameraBackend] instance, or create a new one. If the backend fails
     * to load or is not available, this method will return null.
     */
    operator fun get(backendId: CameraBackendId): CameraBackend?
}
