package com.ustadmobile.core.db.dao

import androidx.lifecycle.LiveData
import androidx.paging.DataSource
import com.ustadmobile.door.ext.doorPrimaryKeyManager
import com.ustadmobile.door.ext.rootDatabase
import com.ustadmobile.door.room.RoomDatabase
import com.ustadmobile.door.util.systemTimeInMillis
import com.ustadmobile.lib.db.entities.ContentEntry
import com.ustadmobile.lib.db.entities.ContentEntryButtonModel
import com.ustadmobile.lib.db.entities.ContentEntryContentJobItemParams
import com.ustadmobile.lib.db.entities.ContentEntryWithBlockAndLanguage
import com.ustadmobile.lib.db.entities.ContentEntryWithLanguage
import com.ustadmobile.lib.db.entities.ContentEntryWithMostRecentContainer
import com.ustadmobile.lib.db.entities.ContentEntryWithParentChildJoinAndMostRecentContainer
import com.ustadmobile.lib.db.entities.ContentEntryWithParentChildJoinAndStatusAndMostRecentContainer
import com.ustadmobile.lib.db.entities.ContentJobItemProgressAndStatus
import com.ustadmobile.lib.db.entities.DistinctCategorySchema
import com.ustadmobile.lib.db.entities.DownloadJobSizeInfo
import com.ustadmobile.lib.db.entities.LangUidAndName
import com.ustadmobile.lib.db.entities.Language
import com.ustadmobile.lib.db.entities.UidAndLabel
import kotlin.Boolean
import kotlin.Int
import kotlin.Long
import kotlin.String
import kotlin.Unit
import kotlin.collections.List

public class ContentEntryDao_ReplicateWrapper(
  private val _db: RoomDatabase,
  private val _dao: ContentEntryDao,
) : ContentEntryDao() {
  public override suspend fun replicateOnNewNode(newNodeId: Long): Unit {
    _dao.replicateOnNewNode(newNodeId)
  }

  public override suspend fun replicateOnChange(): Unit {
    _dao.replicateOnChange()
  }

  public override suspend fun insertListAsync(entityList: List<ContentEntry>): Unit {
    val _pkManager = _db.rootDatabase.doorPrimaryKeyManager
    val _generatedPks = mutableListOf<Long>()
    entityList.iterator().forEach  {
      if(it.contentEntryUid == 0L) {
        val _newPk = _pkManager.nextIdAsync(42)
        it.contentEntryUid = _newPk
        _generatedPks += _newPk
      }
      it.contentEntryLct = systemTimeInMillis()
    }
    //must set versionid and/or primary key here
    _dao.insertListAsync(entityList)
  }

  public override suspend fun findEntryWithLanguageByEntryIdAsync(entryUuid: Long):
      ContentEntryWithLanguage? = _dao.findEntryWithLanguageByEntryIdAsync(entryUuid)

  public override suspend fun findEntryWithBlockAndLanguageByUidAsync(entityUid: Long):
      ContentEntryWithBlockAndLanguage? = _dao.findEntryWithBlockAndLanguageByUidAsync(entityUid)

  public override suspend fun findEntryWithContainerByEntryId(entryUuid: Long):
      ContentEntryWithMostRecentContainer? = _dao.findEntryWithContainerByEntryId(entryUuid)

  public override fun findEntryWithContainerByEntryIdLive(entryUuid: Long):
      LiveData<ContentEntryWithMostRecentContainer?> =
      _dao.findEntryWithContainerByEntryIdLive(entryUuid)

  public override fun findBySourceUrl(sourceUrl: String): ContentEntry? =
      _dao.findBySourceUrl(sourceUrl)

  public override suspend fun findTitleByUidAsync(contentEntryUid: Long): String? =
      _dao.findTitleByUidAsync(contentEntryUid)

  public override fun getChildrenByParentUid(parentUid: Long): DataSource.Factory<Int, ContentEntry>
      = _dao.getChildrenByParentUid(parentUid)

  public override suspend fun getChildrenByParentAsync(parentUid: Long): List<ContentEntry> =
      _dao.getChildrenByParentAsync(parentUid)

  public override suspend fun getContentJobItemParamsByParentUid(
    parentUid: Long,
    limit: Int,
    offset: Int,
  ): List<ContentEntryContentJobItemParams> = _dao.getContentJobItemParamsByParentUid(parentUid,
      limit, offset)

  public override suspend fun getCountNumberOfChildrenByParentUUidAsync(parentUid: Long): Int =
      _dao.getCountNumberOfChildrenByParentUUidAsync(parentUid)

  public override suspend fun getContentByUuidAsync(parentUid: Long): ContentEntry? =
      _dao.getContentByUuidAsync(parentUid)

  public override suspend fun findAllLanguageRelatedEntriesAsync(entryUuid: Long):
      List<ContentEntry> = _dao.findAllLanguageRelatedEntriesAsync(entryUuid)

  public override suspend fun findListOfCategoriesAsync(parentUid: Long):
      List<DistinctCategorySchema> = _dao.findListOfCategoriesAsync(parentUid)

  public override suspend fun findUniqueLanguagesInListAsync(parentUid: Long): List<Language> =
      _dao.findUniqueLanguagesInListAsync(parentUid)

  public override suspend fun findUniqueLanguageWithParentUid(parentUid: Long): List<LangUidAndName>
      = _dao.findUniqueLanguageWithParentUid(parentUid)

  public override fun update(entity: ContentEntry): Unit {
    entity.contentEntryLct = systemTimeInMillis()
    //must set versionid and/or primary key here
    _dao.update(entity)
  }

  public override suspend fun findByUidAsync(entryUid: Long): ContentEntry? =
      _dao.findByUidAsync(entryUid)

  public override suspend fun findByUidWithLanguageAsync(uid: Long): ContentEntryWithLanguage? =
      _dao.findByUidWithLanguageAsync(uid)

  public override fun findByUid(entryUid: Long): ContentEntry? = _dao.findByUid(entryUid)

  public override fun findByTitle(title: String): LiveData<ContentEntry?> = _dao.findByTitle(title)

  public override suspend fun isMeteredAllowedForEntry(contentEntryUid: Long): Boolean =
      _dao.isMeteredAllowedForEntry(contentEntryUid)

  public override suspend fun findBySourceUrlWithContentEntryStatusAsync(sourceUrl: String):
      ContentEntry? = _dao.findBySourceUrlWithContentEntryStatusAsync(sourceUrl)

  public override fun getChildrenByParentUidWithCategoryFilterOrderByName(
    parentUid: Long,
    langParam: Long,
    categoryParam0: Long,
    personUid: Long,
    showHidden: Boolean,
    onlyFolder: Boolean,
    sortOrder: Int,
  ): DataSource.Factory<Int, ContentEntryWithParentChildJoinAndStatusAndMostRecentContainer> =
      _dao.getChildrenByParentUidWithCategoryFilterOrderByName(parentUid, langParam, categoryParam0,
      personUid, showHidden, onlyFolder, sortOrder)

  public override fun getContentFromMyCourses(personUid: Long):
      DataSource.Factory<Int, ContentEntryWithParentChildJoinAndStatusAndMostRecentContainer> =
      _dao.getContentFromMyCourses(personUid)

  public override fun getContentByOwner(personUid: Long):
      DataSource.Factory<Int, ContentEntryWithParentChildJoinAndStatusAndMostRecentContainer> =
      _dao.getContentByOwner(personUid)

  public override suspend fun updateAsync(entity: ContentEntry): Int {
    entity.contentEntryLct = systemTimeInMillis()
    //must set versionid and/or primary key here
    return _dao.updateAsync(entity)
  }

  public override fun getChildrenByAll(parentUid: Long): List<ContentEntry> =
      _dao.getChildrenByAll(parentUid)

  public override fun findLiveContentEntry(parentUid: Long): LiveData<ContentEntry?> =
      _dao.findLiveContentEntry(parentUid)

  public override fun getContentEntryUidFromXapiObjectId(objectId: String): Long =
      _dao.getContentEntryUidFromXapiObjectId(objectId)

  public override fun findSimilarIdEntryForKhan(sourceUrl: String): List<ContentEntry> =
      _dao.findSimilarIdEntryForKhan(sourceUrl)

  public override suspend fun getRecursiveDownloadTotals(contentEntryUid: Long):
      DownloadJobSizeInfo? = _dao.getRecursiveDownloadTotals(contentEntryUid)

  public override fun getAllEntriesRecursively(contentEntryUid: Long):
      DataSource.Factory<Int, ContentEntryWithParentChildJoinAndMostRecentContainer> =
      _dao.getAllEntriesRecursively(contentEntryUid)

  public override fun getAllEntriesRecursivelyAsList(contentEntryUid: Long):
      List<ContentEntryWithParentChildJoinAndMostRecentContainer> =
      _dao.getAllEntriesRecursivelyAsList(contentEntryUid)

  public override fun updateContentEntryInActive(
    contentEntryUid: Long,
    ceInactive: Boolean,
    changedTime: Long,
  ): Unit {
    _dao.updateContentEntryInActive(contentEntryUid, ceInactive, changedTime)
  }

  public override fun updateContentEntryContentFlag(
    contentFlag: Int,
    contentEntryUid: Long,
    changedTime: Long,
  ): Unit {
    _dao.updateContentEntryContentFlag(contentFlag, contentEntryUid, changedTime)
  }

  public override fun replaceList(entries: List<ContentEntry>): Unit {
    val _pkManager = _db.rootDatabase.doorPrimaryKeyManager
    val _generatedPks = mutableListOf<Long>()
    entries.iterator().forEach  {
      if(it.contentEntryUid == 0L) {
        val _newPk = _pkManager.nextId(42)
        it.contentEntryUid = _newPk
        _generatedPks += _newPk
      }
      it.contentEntryLct = systemTimeInMillis()
    }
    //must set versionid and/or primary key here
    _dao.replaceList(entries)
  }

  public override suspend fun getContentEntryFromUids(contentEntryUids: List<Long>):
      List<UidAndLabel> = _dao.getContentEntryFromUids(contentEntryUids)

  public override fun insertWithReplace(entry: ContentEntry): Unit {
    val _pkManager = _db.rootDatabase.doorPrimaryKeyManager
    if(entry.contentEntryUid == 0L) {
      val _newPk = _pkManager.nextId(42)
      entry.contentEntryUid = _newPk
    }
    entry.contentEntryLct = systemTimeInMillis()
    //must set versionid and/or primary key here
    _dao.insertWithReplace(entry)
  }

  public override fun findAllLive(): LiveData<List<ContentEntryWithLanguage>> = _dao.findAllLive()

  public override suspend fun personHasPermissionWithContentEntry(
    accountPersonUid: Long,
    contentEntryUid: Long,
    permission: Long,
  ): Boolean = _dao.personHasPermissionWithContentEntry(accountPersonUid, contentEntryUid,
      permission)

  public override suspend fun updateContentEntryActiveByContentJobUid(
    jobId: Long,
    inactive: Boolean,
    changedTime: Long,
  ): Unit {
    _dao.updateContentEntryActiveByContentJobUid(jobId, inactive, changedTime)
  }

  public override suspend fun toggleVisibilityContentEntryItems(
    toggleVisibility: Boolean,
    selectedItem: List<Long>,
    changedTime: Long,
  ): Unit {
    _dao.toggleVisibilityContentEntryItems(toggleVisibility, selectedItem, changedTime)
  }

  public override suspend
      fun findContentEntriesWhereIsLeafAndLatestContainerHasNoEntriesOrHasZeroFileSize():
      List<ContentEntry> =
      _dao.findContentEntriesWhereIsLeafAndLatestContainerHasNoEntriesOrHasZeroFileSize()

  public override suspend fun buttonsToShowForContentEntry(contentEntryUid: Long,
      platformDownloadEnabled: Boolean): ContentEntryButtonModel? =
      _dao.buttonsToShowForContentEntry(contentEntryUid, platformDownloadEnabled)

  public override suspend fun statusForDownloadDialog(contentEntryUid: Long): Int =
      _dao.statusForDownloadDialog(contentEntryUid)

  public override suspend fun statusForContentEntryList(contentEntryUid: Long):
      ContentJobItemProgressAndStatus? = _dao.statusForContentEntryList(contentEntryUid)

  public override fun insert(entity: ContentEntry): Long {
    val _pkManager = _db.rootDatabase.doorPrimaryKeyManager
    if(entity.contentEntryUid == 0L) {
      val _newPk = _pkManager.nextId(42)
      entity.contentEntryUid = _newPk
    }
    entity.contentEntryLct = systemTimeInMillis()
    //must set versionid and/or primary key here
    _dao.insert(entity)
    return entity.contentEntryUid
  }

  public override suspend fun insertAsync(entity: ContentEntry): Long {
    val _pkManager = _db.rootDatabase.doorPrimaryKeyManager
    if(entity.contentEntryUid == 0L) {
      val _newPk = _pkManager.nextIdAsync(42)
      entity.contentEntryUid = _newPk
    }
    entity.contentEntryLct = systemTimeInMillis()
    //must set versionid and/or primary key here
    _dao.insertAsync(entity)
    return entity.contentEntryUid
  }

  public override fun insertList(entityList: List<ContentEntry>): Unit {
    val _pkManager = _db.rootDatabase.doorPrimaryKeyManager
    val _generatedPks = mutableListOf<Long>()
    entityList.iterator().forEach  {
      if(it.contentEntryUid == 0L) {
        val _newPk = _pkManager.nextId(42)
        it.contentEntryUid = _newPk
        _generatedPks += _newPk
      }
      it.contentEntryLct = systemTimeInMillis()
    }
    //must set versionid and/or primary key here
    _dao.insertList(entityList)
  }

  public override fun updateList(entityList: List<ContentEntry>): Unit {
    val _generatedPks = mutableListOf<Long>()
    entityList.iterator().forEach  {
      it.contentEntryLct = systemTimeInMillis()
    }
    //must set versionid and/or primary key here
    _dao.updateList(entityList)
  }
}
