package com.ustadmobile.core.db.dao

import androidx.lifecycle.LiveData
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.Container
import com.ustadmobile.lib.db.entities.ContainerUidAndMimeType
import com.ustadmobile.lib.db.entities.ContainerWithContentEntry
import kotlin.Boolean
import kotlin.Long
import kotlin.String
import kotlin.Unit
import kotlin.collections.List

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

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

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

  public override suspend
      fun getMostRecentDownloadedContainerForContentEntryAsync(contentEntry: Long): Container? =
      _dao.getMostRecentDownloadedContainerForContentEntryAsync(contentEntry)

  public override fun getMostRecentContainerForContentEntry(contentEntryUid: Long): Container? =
      _dao.getMostRecentContainerForContentEntry(contentEntryUid)

  public override fun findByUid(uid: Long): Container? = _dao.findByUid(uid)

  public override suspend fun findSizeByUid(uid: Long): Long = _dao.findSizeByUid(uid)

  public override suspend
      fun findRecentContainerToBeMonitoredWithEntriesUid(contentEntries: List<Long>):
      List<Container> = _dao.findRecentContainerToBeMonitoredWithEntriesUid(contentEntries)

  public override suspend fun findContainersForContentEntryUid(contentEntryUid: Long):
      List<Container> = _dao.findContainersForContentEntryUid(contentEntryUid)

  public override fun hasContainerWithFilesToDownload(contentEntryUid: Long): LiveData<Boolean> =
      _dao.hasContainerWithFilesToDownload(contentEntryUid)

  public override suspend fun findContainerWithFilesByContentEntryUid(contentEntryUid: Long):
      Container? = _dao.findContainerWithFilesByContentEntryUid(contentEntryUid)

  public override fun findAllPublikContainers(): List<Container> = _dao.findAllPublikContainers()

  public override suspend fun findByUidAsync(containerUid: Long): Container? =
      _dao.findByUidAsync(containerUid)

  public override suspend fun updateContainerSizeAndNumEntriesAsync(containerUid: Long,
      changeTime: Long): Unit {
    _dao.updateContainerSizeAndNumEntriesAsync(containerUid, changeTime)
  }

  public override fun findLocalAvailabilityByUid(containerUid: Long): Long =
      _dao.findLocalAvailabilityByUid(containerUid)

  public override fun findAllWithId(containerUid: Long): List<Container> =
      _dao.findAllWithId(containerUid)

  public override fun findKhanContainers(): List<ContainerWithContentEntry> =
      _dao.findKhanContainers()

  public override fun deleteByUid(containerUid: Long): Unit {
    _dao.deleteByUid(containerUid)
  }

  public override fun updateMimeType(mimeType: String, containerUid: Long): Unit {
    _dao.updateMimeType(mimeType, containerUid)
  }

  public override suspend fun getMostRecentContainerForContentEntryAsync(contentEntryUid: Long):
      Container? = _dao.getMostRecentContainerForContentEntryAsync(contentEntryUid)

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

  public override suspend fun getMostRecentAvailableContainerUidAndMimeType(contentEntryUid: Long,
      downloadRequired: Boolean): ContainerUidAndMimeType? =
      _dao.getMostRecentAvailableContainerUidAndMimeType(contentEntryUid, downloadRequired)

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

  public override fun insertWithReplace(container: Container): Unit {
    val _pkManager = _db.rootDatabase.doorPrimaryKeyManager
    if(container.containerUid == 0L) {
      val _newPk = _pkManager.nextId(51)
      container.containerUid = _newPk
    }
    container.cntLct = systemTimeInMillis()
    //must set versionid and/or primary key here
    _dao.insertWithReplace(container)
  }

  public override suspend fun getContainerSizeByUid(containerUid: Long): Long =
      _dao.getContainerSizeByUid(containerUid)

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

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

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

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

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