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.CourseGroupSet
import kotlin.Int
import kotlin.Long
import kotlin.Unit
import kotlin.collections.List

@Dao
public actual abstract class CourseGroupSetDao : BaseDao<CourseGroupSet> {
  @Query(`value` =
      "\n     REPLACE INTO CourseGroupSetReplicate(cgsPk, cgsDestination)\n      SELECT DISTINCT CourseGroupSet.cgsUid AS cgsUid,\n             :newNodeId AS cgsDestination\n        FROM UserSession\n             JOIN PersonGroupMember \n                    ON UserSession.usPersonUid = PersonGroupMember.groupMemberPersonUid\n             \n               JOIN ScopedGrant\n                    ON ScopedGrant.sgGroupUid = PersonGroupMember.groupMemberGroupUid\n                        AND (ScopedGrant.sgPermissions & \n        \n                    2 \n                    \n                       ) > 0\n               JOIN Clazz \n                    ON \n            ((ScopedGrant.sgTableId = -2\n                                AND ScopedGrant.sgEntityUid = -2)\n                            OR (ScopedGrant.sgTableId = 6\n                                AND ScopedGrant.sgEntityUid = Clazz.clazzUid)\n                            OR (ScopedGrant.sgTableId = 164\n                                AND ScopedGrant.sgEntityUid = Clazz.clazzSchoolUid))\n        \n        \n             JOIN CourseGroupSet\n                    ON CourseGroupSet.cgsClazzUid = Clazz.clazzUid\n       WHERE UserSession.usClientNodeId = :newNodeId\n         AND UserSession.usStatus = 1\n         AND CourseGroupSet.cgsLct != COALESCE(\n             (SELECT cgsVersionId\n                FROM CourseGroupSetReplicate\n               WHERE cgsPk = CourseGroupSet.cgsUid\n                 AND cgsDestination = :newNodeId), 0) \n      /*psql ON CONFLICT(cgsPk, cgsDestination) DO UPDATE\n             SET cgsPending = true\n      */       \n    ")
  public actual abstract suspend fun replicateOnNewNode(newNodeId: Long): Unit

  @Query(`value` =
      "\n REPLACE INTO CourseGroupSetReplicate(cgsPk, cgsDestination)\n  SELECT DISTINCT CourseGroupSet.cgsUid AS cgsUid,\n         UserSession.usClientNodeId AS cgsDestination\n    FROM ChangeLog\n         JOIN CourseGroupSet\n             ON ChangeLog.chTableId = 242\n                AND ChangeLog.chEntityPk = CourseGroupSet.cgsUid\n         JOIN Clazz \n              ON Clazz.clazzUid = CourseGroupSet.cgsClazzUid \n         \n            JOIN ScopedGrant\n                 ON \n            ((ScopedGrant.sgTableId = -2\n                                AND ScopedGrant.sgEntityUid = -2)\n                            OR (ScopedGrant.sgTableId = 6\n                                AND ScopedGrant.sgEntityUid = Clazz.clazzUid)\n                            OR (ScopedGrant.sgTableId = 164\n                                AND ScopedGrant.sgEntityUid = Clazz.clazzSchoolUid))\n        \n                    AND (ScopedGrant.sgPermissions & \n        \n              8388608\n              \n              \n                                                       ) > 0\n             JOIN PersonGroupMember AS PrsGrpMbr\n                   ON ScopedGrant.sgGroupUid = PrsGrpMbr.groupMemberGroupUid\n                                               \n              JOIN UserSession\n                   ON UserSession.usPersonUid = PrsGrpMbr.groupMemberPersonUid\n                      AND UserSession.usStatus = 1\n          \n   WHERE UserSession.usClientNodeId != (\n         SELECT nodeClientId \n           FROM SyncNode\n          LIMIT 1)\n     AND CourseGroupSet.cgsLct != COALESCE(\n         (SELECT cgsVersionId\n            FROM CourseGroupSetReplicate\n           WHERE cgsPk = CourseGroupSet.cgsUid\n             AND cgsDestination = UserSession.usClientNodeId), 0)\n /*psql ON CONFLICT(cgsPk, cgsDestination) DO UPDATE\n     SET cgsPending = true\n  */               \n ")
  public actual abstract suspend fun replicateOnChange(): Unit

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

  @Query(`value` =
      "\n        SELECT *\n         FROM CourseGroupSet\n        WHERE cgsActive\n          AND cgsClazzUid = :clazzUid\n     ORDER BY cgsName   \n    ")
  public actual abstract fun findAllCourseGroupSetForClazz(clazzUid: Long):
      DataSource.Factory<Int, CourseGroupSet>

  @Query(`value` =
      "\n        SELECT *\n         FROM CourseGroupSet\n        WHERE cgsActive\n          AND cgsClazzUid = :clazzUid\n     ORDER BY cgsName   \n    ")
  public actual abstract fun findAllCourseGroupSetForClazzList(clazzUid: Long): List<CourseGroupSet>

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