package com.ustadmobile.core.catalog.contenttype

import com.ustadmobile.core.db.UmAppDatabase
import com.ustadmobile.lib.db.entities.Container
import com.ustadmobile.lib.db.entities.ContentEntryWithLanguage

/**
 * A ContentTypePlugin provides support to use a specific file type (e.g. EPUB, Xapi Package, etc) on
 * Ustad Mobile. Specifically a plugin is responsible to:
 *
 * a. Read a file type and return information about it including a unique id and a title.
 * b. Provide the view name that will be used to view that item.
 *
 * Created by mike on 9/9/17.
 */
interface ContentTypePlugin {

    /**
     * Return a String that will match the VIEW_NAME for the view that should be opened for this
     * type of content
     *
     * @return Name of view to open for this type of content
     */
    val viewName: String

    /**
     * Return an array of mime types that are used by this content type.
     *
     * @return
     */
    val mimeTypes: Array<String>

    /**
     * Return an array of file extensions that can be used by this content type
     */
    val fileExtensions: Array<String>

    /**
     * This should extract metadata from the given uri. This must switch to using a
     * background coroutine context (e.g. withContext(Dispatchers.Default). This MUST validate the
     * content of the underlying data.
     *
     * @return ContentEntryWithLanguage if successful and this can be imported, null otherwise
     */
    suspend fun extractMetadata(uri: String, context: Any): ContentEntryWithLanguage?

    /**
     * This should import the content itself into a Container. This may involve performing
     * additional compression and conversion on the Container (e.g. converting a video into a
     * mobile-optimized codec, converting images inside an EPUB to webp, etc).
     *
     * @param uri that should be imported
     * @param conversionParams a string map of parameters that can be used to control import settings
     * @param db to create containerManager
     * @param repo to create containerManager
     * @param progressListener function that will be invoked periodically during the import
     *
     * @return Container that was generated by importing the given file
     * @throws IOException if an underlying IOError happens, or other exceptions could be thrown in
     * case of invalid data. importToContainer should only be called after validating with extractMetadata
     */
    suspend fun importToContainer(uri: String, conversionParams: Map<String, String>,
                                  contentEntryUid: Long, mimeType: String,
                                  containerBaseDir: String,
                                  context: Any, db: UmAppDatabase,
                                  repo: UmAppDatabase,
                                  progressListener: (Int) -> Unit): Container


    companion object {

        const val CONTENT_ENTRY = "content_entry"

        const val CONTENT_MIMETYPE = "content_mimetype"
    }


}
