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.Clazz
import com.ustadmobile.lib.db.entities.ClazzWithDisplayDetails
import com.ustadmobile.lib.db.entities.ClazzWithHolidayCalendarAndSchoolAndTerminology
import com.ustadmobile.lib.db.entities.ClazzWithListDisplayDetails
import com.ustadmobile.lib.db.entities.ClazzWithSchool
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 ClazzDao_ReplicateWrapper(
  private val _db: RoomDatabase,
  private val _dao: ClazzDao,
) : ClazzDao() {
  public override suspend fun replicateOnNewNode(newNodeId: Long): Unit {
    _dao.replicateOnNewNode(newNodeId)
  }

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

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

  public override fun findByUidLive(uid: Long): LiveData<Clazz?> = _dao.findByUidLive(uid)

  public override suspend fun findByClazzCode(code: String): Clazz? = _dao.findByClazzCode(code)

  public override suspend fun findByClazzCodeFromWeb(code: String): Clazz? =
      _dao.findByClazzCodeFromWeb(code)

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

  public override fun findAll(): List<Clazz> = _dao.findAll()

  public override suspend fun findByUidAsync(uid: Long): Clazz? = _dao.findByUidAsync(uid)

  public override suspend fun findByUidWithHolidayCalendarAsync(uid: Long):
      ClazzWithHolidayCalendarAndSchoolAndTerminology? = _dao.findByUidWithHolidayCalendarAsync(uid)

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

  public override suspend fun findAllClazzesBySchool(schoolUid: Long): List<Clazz> =
      _dao.findAllClazzesBySchool(schoolUid)

  public override fun findAllClazzesBySchoolLive(schoolUid: Long): DataSource.Factory<Int, Clazz> =
      _dao.findAllClazzesBySchoolLive(schoolUid)

  public override fun findClazzesWithPermission(
    searchQuery: String,
    accountPersonUid: Long,
    excludeSelectedClazzList: List<Long>,
    excludeSchoolUid: Long,
    sortOrder: Int,
    filter: Int,
    currentTime: Long,
    permission: Long,
    selectedSchool: Long,
  ): DataSource.Factory<Int, ClazzWithListDisplayDetails> =
      _dao.findClazzesWithPermission(searchQuery, accountPersonUid, excludeSelectedClazzList,
      excludeSchoolUid, sortOrder, filter, currentTime, permission, selectedSchool)

  public override suspend fun getClassNamesFromListOfIds(ids: List<Long>): List<UidAndLabel> =
      _dao.getClassNamesFromListOfIds(ids)

  public override fun findByClazzName(name: String): List<Clazz> = _dao.findByClazzName(name)

  public override suspend fun updateClazzAttendanceAverageAsync(clazzUid: Long, timeChanged: Long):
      Unit {
    _dao.updateClazzAttendanceAverageAsync(clazzUid, timeChanged)
  }

  public override suspend fun personHasPermissionWithClazz(
    accountPersonUid: Long,
    clazzUid: Long,
    permission: Long,
  ): Boolean = _dao.personHasPermissionWithClazz(accountPersonUid, clazzUid, permission)

  public override suspend fun selectDelegatablePermissions(accountPersonUid: Long, clazzUid: Long):
      List<Long> = _dao.selectDelegatablePermissions(accountPersonUid, clazzUid)

  public override fun getClazzWithDisplayDetails(clazzUid: Long, currentTime: Long):
      LiveData<ClazzWithDisplayDetails?> = _dao.getClazzWithDisplayDetails(clazzUid, currentTime)

  public override fun findClazzesWithEffectiveHolidayCalendarAndFilter(filterUid: Long):
      List<ClazzWithHolidayCalendarAndSchoolAndTerminology> =
      _dao.findClazzesWithEffectiveHolidayCalendarAndFilter(filterUid)

  public override suspend fun getClazzWithSchool(clazzUid: Long): ClazzWithSchool? =
      _dao.getClazzWithSchool(clazzUid)

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

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

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

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

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