package com.ustadmobile.core.db.dao

import androidx.paging.DataSource
import androidx.room.Dao
import androidx.room.Query
import androidx.room.Update
import com.ustadmobile.lib.db.entities.CourseTerminology
import kotlin.Int
import kotlin.Long
import kotlin.Unit
import kotlin.collections.List

@Dao
public actual abstract class CourseTerminologyDao : BaseDao<CourseTerminology> {
  @Query(`value` =
      "\n     REPLACE INTO CourseTerminologyReplicate(ctPk, ctDestination)\n      SELECT DISTINCT CourseTerminology.ctUid AS ctPk,\n             :newNodeId AS ctDestination\n        FROM CourseTerminology\n       WHERE CourseTerminology.ctLct != COALESCE(\n             (SELECT ctVersionId\n                FROM CourseTerminologyReplicate\n               WHERE ctPk = CourseTerminology.ctUid\n                 AND ctDestination = :newNodeId), 0) \n      /*psql ON CONFLICT(ctPk, ctDestination) DO UPDATE\n             SET ctPending = true\n      */       \n    ")
  public actual abstract suspend fun replicateOnNewNode(newNodeId: Long): Unit

  @Query(`value` =
      "\n REPLACE INTO CourseTerminologyReplicate(ctPk, ctDestination)\n  SELECT DISTINCT CourseTerminology.ctUid AS ctUid,\n         UserSession.usClientNodeId AS ctDestination\n    FROM ChangeLog\n         JOIN CourseTerminology\n             ON ChangeLog.chTableId = 450\n                AND ChangeLog.chEntityPk = CourseTerminology.ctUid\n         JOIN UserSession ON UserSession.usStatus = 1\n   WHERE UserSession.usClientNodeId != (\n         SELECT nodeClientId \n           FROM SyncNode\n          LIMIT 1)\n     AND CourseTerminology.ctLct != COALESCE(\n         (SELECT ctVersionId\n            FROM CourseTerminologyReplicate\n           WHERE ctPk = CourseTerminology.ctUid\n             AND ctDestination = UserSession.usClientNodeId), 0)\n /*psql ON CONFLICT(ctPk, ctDestination) DO UPDATE\n     SET ctPending = true\n  */               \n    ")
  public actual abstract suspend fun replicateOnChange(): Unit

  @Query(`value` =
      "\n        SELECT *\n         FROM CourseTerminology\n     ORDER BY ctTitle   \n    ")
  public actual abstract fun findAllCourseTerminology(): DataSource.Factory<Int, CourseTerminology>

  @Query(`value` =
      "\n        SELECT *\n         FROM CourseTerminology\n     ORDER BY ctTitle   \n    ")
  public actual abstract fun findAllCourseTerminologyList(): List<CourseTerminology>

  @Query(`value` =
      "\n        SELECT *\n          FROM CourseTerminology\n               JOIN Clazz \n               ON Clazz.clazzTerminologyUid = CourseTerminology.ctUid\n         WHERE Clazz.clazzUid = :clazzUid\n    ")
  public actual abstract suspend fun getTerminologyForClazz(clazzUid: Long): CourseTerminology?

  @Query(`value` =
      "\n        SELECT * \n         FROM CourseTerminology \n        WHERE ctUid = :uid\n        ")
  public actual abstract suspend fun findByUidAsync(uid: Long): CourseTerminology?

  @Update(onConflict = 3)
  public actual abstract suspend fun updateAsync(entity: CourseTerminology): Int
}
