package com.ustadmobile.core.db.dao

import androidx.paging.PagingSource
import androidx.room.Dao
import androidx.room.Query
import androidx.room.Update
import com.ustadmobile.lib.db.composites.ClazzAndDetailPermissions
import com.ustadmobile.lib.db.composites.ClazzAndDisplayDetails
import com.ustadmobile.lib.db.composites.ClazzNameAndTerminology
import com.ustadmobile.lib.db.entities.Clazz
import com.ustadmobile.lib.db.entities.ClazzWithHolidayCalendarAndAndTerminology
import com.ustadmobile.lib.db.entities.ClazzWithListDisplayDetails
import com.ustadmobile.lib.db.entities.UidAndLabel
import kotlin.Any
import kotlin.Boolean
import kotlin.Int
import kotlin.Long
import kotlin.String
import kotlin.collections.List
import kotlinx.coroutines.flow.Flow

@Dao
public actual abstract class ClazzDao : BaseDao<Clazz> {
  @Query(`value` = "SELECT * FROM Clazz WHERE clazzUid = :uid")
  public actual abstract fun findByUid(uid: Long): Clazz?

  @Query(`value` = "SELECT * From Clazz WHERE clazzUid = :uid")
  public actual abstract fun findByUidLive(uid: Long): Flow<Clazz?>

  @Query(`value` = "SELECT * FROM Clazz WHERE clazzCode = :code")
  public actual abstract suspend fun findByClazzCode(code: String): Clazz?

  @Query(`value` = "SELECT * FROM Clazz WHERE clazzCode = :code")
  public actual abstract suspend fun findByClazzCodeFromWeb(code: String): Clazz?

  @Query(`value` = "SELECT * FROM Clazz WHERE CAST(isClazzActive AS INTEGER) = 1")
  public actual abstract fun findAllLive(): Flow<List<Clazz>>

  @Query(`value` = "SELECT * FROM Clazz WHERE CAST(isClazzActive AS INTEGER) = 1")
  public actual abstract fun findAll(): List<Clazz>

  @Query(`value` = "SELECT * FROM Clazz WHERE clazzUid = :clazzUid")
  public actual abstract suspend fun findByUidAsync(clazzUid: Long): Clazz?

  @Query(`value` =
      "\n        SELECT EXISTS(\n               SELECT Clazz.clazzUid\n                 FROM Clazz\n                WHERE Clazz.clazzUid = :clazzUid)\n    ")
  public actual abstract suspend fun clazzUidExistsAsync(clazzUid: Long): Boolean

  @Query(`value` = "SELECT * FROM Clazz WHERE clazzUid = :uid")
  public actual abstract fun findByUidAsFlow(uid: Long): Flow<Clazz?>

  @Query(`value` =
      "\n        SELECT Clazz.*, \n               CoursePicture.*,\n               HolidayCalendar.*, \n               CourseTerminology.*\n          FROM Clazz \n               LEFT JOIN HolidayCalendar \n                         ON Clazz.clazzHolidayUMCalendarUid = HolidayCalendar.umCalendarUid\n\n               LEFT JOIN CourseTerminology\n                         ON CourseTerminology.ctUid = Clazz.clazzTerminologyUid\n                      \n               LEFT JOIN CoursePicture\n                         ON CoursePicture.coursePictureUid = :uid\n         WHERE Clazz.clazzUid = :uid")
  public actual abstract suspend fun findByUidWithHolidayCalendarAsync(uid: Long):
      ClazzWithHolidayCalendarAndAndTerminology?

  @Update(
    entity = Any::class,
    onConflict = 3,
  )
  public actual abstract suspend fun updateAsync(entity: Clazz): Int

  @Query(`value` =
      "\n        SELECT Clazz.*, ClazzEnrolment.*, CoursePicture.*,\n               (SELECT COUNT(DISTINCT ClazzEnrolment.clazzEnrolmentPersonUid) \n                  FROM ClazzEnrolment \n                 WHERE ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid \n                   AND clazzEnrolmentRole = 1000 \n                   AND :currentTime BETWEEN ClazzEnrolment.clazzEnrolmentDateJoined \n                       AND ClazzEnrolment.clazzEnrolmentDateLeft) AS numStudents,\n               (SELECT COUNT(DISTINCT ClazzEnrolment.clazzEnrolmentPersonUid) \n                  FROM ClazzEnrolment \n                 WHERE ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid \n                   AND clazzEnrolmentRole = 1001\n                   AND :currentTime BETWEEN ClazzEnrolment.clazzEnrolmentDateJoined \n                        AND ClazzEnrolment.clazzEnrolmentDateLeft) AS numTeachers,\n               '' AS teacherNames,\n               0 AS lastRecorded,\n               CourseTerminology.*\n          FROM Clazz\n               LEFT JOIN ClazzEnrolment \n                    ON ClazzEnrolment.clazzEnrolmentUid =\n                       COALESCE(\n                       (SELECT ClazzEnrolment.clazzEnrolmentUid \n                          FROM ClazzEnrolment\n                         WHERE ClazzEnrolment.clazzEnrolmentPersonUid = :accountPersonUid\n                           AND ClazzEnrolment.clazzEnrolmentActive\n                           AND ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid \n                      ORDER BY ClazzEnrolment.clazzEnrolmentDateLeft DESC   \n                         LIMIT 1), 0)\n                LEFT JOIN CourseTerminology   \n                          ON CourseTerminology.ctUid = Clazz.clazzTerminologyUid\n                LEFT JOIN CoursePicture\n                          ON CoursePicture.coursePictureUid = Clazz.clazzUid           \n\n         WHERE /* Begin permission check clause */\n               :accountPersonUid != 0\n           AND (\n                    Clazz.clazzOwnerPersonUid = :accountPersonUid\n                 OR EXISTS(SELECT CoursePermission.cpUid\n                             FROM CoursePermission\n                            WHERE CoursePermission.cpClazzUid = Clazz.clazzUid\n                              AND (   CoursePermission.cpToPersonUid = :accountPersonUid \n                                   OR CoursePermission.cpToEnrolmentRole = ClazzEnrolment.clazzEnrolmentRole )\n                              AND (CoursePermission.cpPermissionsFlag & :permission) > 0 \n                              AND NOT CoursePermission.cpIsDeleted)   \n                 OR (\n        SELECT \n        EXISTS(SELECT 1\n                 FROM SystemPermission\n                WHERE :accountPersonUid != 0 \n                  AND SystemPermission.spToPersonUid = :accountPersonUid\n                  AND (SystemPermission.spPermissionsFlag &\n    \n          :permission\n        \n        ) > 0\n                  AND NOT SystemPermission.spIsDeleted)\n      \n    )             \n                )\n                /* End permission check clause */ \n           AND CAST(Clazz.isClazzActive AS INTEGER) = 1\n           AND Clazz.clazzName like :searchQuery\n           AND (Clazz.clazzUid NOT IN (:excludeSelectedClazzList))\n           AND ( :filter = 0 OR (CASE WHEN :filter = 5 \n                                      THEN :currentTime BETWEEN Clazz.clazzStartTime AND Clazz.clazzEndTime\n                                      ELSE :currentTime > Clazz.clazzEndTime \n                                      END))\n      GROUP BY Clazz.clazzUid, ClazzEnrolment.clazzEnrolmentUid, CourseTerminology.ctUid, CoursePicture.coursePictureUid\n      ORDER BY CASE :sortOrder\n               WHEN 3 THEN Clazz.attendanceAverage\n               ELSE 0\n               END ASC,\n               CASE :sortOrder\n               WHEN 1 THEN Clazz.clazzName\n               ELSE ''\n               END ASC,\n               CASE :sortOrder\n               WHEN 4 THEN Clazz.attendanceAverage\n               ELSE 0\n               END DESC,\n               CASE :sortOrder\n               WHEN 2 THEN clazz.Clazzname\n               ELSE ''\n               END DESC\n    ")
  public actual abstract fun findClazzesWithPermission(
    searchQuery: String,
    accountPersonUid: Long,
    excludeSelectedClazzList: List<Long>,
    sortOrder: Int,
    filter: Int,
    currentTime: Long,
    permission: Long,
  ): PagingSource<Int, ClazzWithListDisplayDetails>

  @Query(`value` =
      "SELECT Clazz.clazzUid AS uid, Clazz.clazzName AS labelName From Clazz WHERE clazzUid IN (:ids)")
  public actual abstract suspend fun getClassNamesFromListOfIds(ids: List<Long>): List<UidAndLabel>

  @Query(`value` =
      "SELECT * FROM Clazz WHERE clazzName = :name and CAST(isClazzActive AS INTEGER) = 1")
  public actual abstract fun findByClazzName(name: String): List<Clazz>

  @Query(`value` =
      "\n        UPDATE Clazz \n           SET attendanceAverage = \n               COALESCE(CAST(\n                    (SELECT SUM(clazzLogNumPresent) \n                       FROM ClazzLog \n                      WHERE clazzLogClazzUid = :clazzUid\n                       AND clazzLogStatusFlag = 4) AS REAL) /\n                    \n                    CAST(MAX(1.0, \n                        (SELECT SUM(clazzLogNumPresent) + SUM(clazzLogNumPartial) + SUM(clazzLogNumAbsent)\n                        FROM ClazzLog \n                       WHERE clazzLogClazzUid = :clazzUid \n                        AND clazzLogStatusFlag = 4)) AS REAL), 0),\n               clazzLct = :timeChanged         \n         WHERE clazzUid = :clazzUid\n    ")
  public actual abstract suspend fun updateClazzAttendanceAverageAsync(clazzUid: Long,
      timeChanged: Long)

  @Query(`value` =
      "\n        SELECT Clazz.*,\n               (  (\n             /* If the accountPersonUid is the owner of the course, all permissions are granted */\n             (COALESCE(\n                          (SELECT _Clazz_Permission.clazzOwnerPersonUid \n                             FROM Clazz _Clazz_Permission\n                            WHERE _Clazz_Permission.clazzUid = :clazzUid), 0) = :accountPersonUid)\n              /* \n              If there is a CoursePermission entity that is for the course as per the clazzUid\n              parameter that is granted to the person directly or to the enrolmentRole that the \n              person has in the course, then permission is granted.\n              */              \n              OR EXISTS(SELECT CoursePermission.cpUid\n                          FROM CoursePermission\n                               \n        LEFT JOIN ClazzEnrolment ClazzEnrolment_ForAccountPerson \n                        ON CoursePermission.cpToEnrolmentRole != 0\n                       AND ClazzEnrolment_ForAccountPerson.clazzEnrolmentUid = \n                           (SELECT COALESCE(\n                                   (SELECT _ClazzEnrolment_AccountPersonInner.clazzEnrolmentUid \n                                      FROM ClazzEnrolment _ClazzEnrolment_AccountPersonInner\n                                     WHERE _ClazzEnrolment_AccountPersonInner.clazzEnrolmentClazzUid = CoursePermission.cpClazzUid\n                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentPersonUid = :accountPersonUid\n                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentActive\n                                  ORDER BY _ClazzEnrolment_AccountPersonInner.clazzEnrolmentDateLeft DESC   \n                                     LIMIT 1), 0))\n    \n                         WHERE CoursePermission.cpClazzUid = :clazzUid\n                           AND (CoursePermission.cpToPersonUid = :accountPersonUid \n                                OR CoursePermission.cpToEnrolmentRole = ClazzEnrolment_ForAccountPerson.clazzEnrolmentRole)\n                           AND (CoursePermission.cpPermissionsFlag & \n         \n                  32\n                  \n        ) > 0)\n              OR EXISTS(SELECT SystemPermission.spUid\n                          FROM SystemPermission\n                         WHERE SystemPermission.spToPersonUid = :accountPersonUid\n                           AND (SystemPermission.spPermissionsFlag & \n    \n                  32\n                  \n        ) > 0)\n               )\n    \n               ) AS hasAttendancePermission,\n               (  (\n             /* If the accountPersonUid is the owner of the course, all permissions are granted */\n             (COALESCE(\n                          (SELECT _Clazz_Permission.clazzOwnerPersonUid \n                             FROM Clazz _Clazz_Permission\n                            WHERE _Clazz_Permission.clazzUid = :clazzUid), 0) = :accountPersonUid)\n              /* \n              If there is a CoursePermission entity that is for the course as per the clazzUid\n              parameter that is granted to the person directly or to the enrolmentRole that the \n              person has in the course, then permission is granted.\n              */              \n              OR EXISTS(SELECT CoursePermission.cpUid\n                          FROM CoursePermission\n                               \n        LEFT JOIN ClazzEnrolment ClazzEnrolment_ForAccountPerson \n                        ON CoursePermission.cpToEnrolmentRole != 0\n                       AND ClazzEnrolment_ForAccountPerson.clazzEnrolmentUid = \n                           (SELECT COALESCE(\n                                   (SELECT _ClazzEnrolment_AccountPersonInner.clazzEnrolmentUid \n                                      FROM ClazzEnrolment _ClazzEnrolment_AccountPersonInner\n                                     WHERE _ClazzEnrolment_AccountPersonInner.clazzEnrolmentClazzUid = CoursePermission.cpClazzUid\n                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentPersonUid = :accountPersonUid\n                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentActive\n                                  ORDER BY _ClazzEnrolment_AccountPersonInner.clazzEnrolmentDateLeft DESC   \n                                     LIMIT 1), 0))\n    \n                         WHERE CoursePermission.cpClazzUid = :clazzUid\n                           AND (CoursePermission.cpToPersonUid = :accountPersonUid \n                                OR CoursePermission.cpToEnrolmentRole = ClazzEnrolment_ForAccountPerson.clazzEnrolmentRole)\n                           AND (CoursePermission.cpPermissionsFlag & \n         \n                  8192\n                  \n        ) > 0)\n              OR EXISTS(SELECT SystemPermission.spUid\n                          FROM SystemPermission\n                         WHERE SystemPermission.spToPersonUid = :accountPersonUid\n                           AND (SystemPermission.spPermissionsFlag & \n    \n                  8192\n                  \n        ) > 0)\n               )\n    \n               ) AS hasViewMembersPermission,\n               (  (\n             /* If the accountPersonUid is the owner of the course, all permissions are granted */\n             (COALESCE(\n                          (SELECT _Clazz_Permission.clazzOwnerPersonUid \n                             FROM Clazz _Clazz_Permission\n                            WHERE _Clazz_Permission.clazzUid = :clazzUid), 0) = :accountPersonUid)\n              /* \n              If there is a CoursePermission entity that is for the course as per the clazzUid\n              parameter that is granted to the person directly or to the enrolmentRole that the \n              person has in the course, then permission is granted.\n              */              \n              OR EXISTS(SELECT CoursePermission.cpUid\n                          FROM CoursePermission\n                               \n        LEFT JOIN ClazzEnrolment ClazzEnrolment_ForAccountPerson \n                        ON CoursePermission.cpToEnrolmentRole != 0\n                       AND ClazzEnrolment_ForAccountPerson.clazzEnrolmentUid = \n                           (SELECT COALESCE(\n                                   (SELECT _ClazzEnrolment_AccountPersonInner.clazzEnrolmentUid \n                                      FROM ClazzEnrolment _ClazzEnrolment_AccountPersonInner\n                                     WHERE _ClazzEnrolment_AccountPersonInner.clazzEnrolmentClazzUid = CoursePermission.cpClazzUid\n                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentPersonUid = :accountPersonUid\n                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentActive\n                                  ORDER BY _ClazzEnrolment_AccountPersonInner.clazzEnrolmentDateLeft DESC   \n                                     LIMIT 1), 0))\n    \n                         WHERE CoursePermission.cpClazzUid = :clazzUid\n                           AND (CoursePermission.cpToPersonUid = :accountPersonUid \n                                OR CoursePermission.cpToEnrolmentRole = ClazzEnrolment_ForAccountPerson.clazzEnrolmentRole)\n                           AND (CoursePermission.cpPermissionsFlag & \n         \n                  128\n                  \n        ) > 0)\n              OR EXISTS(SELECT SystemPermission.spUid\n                          FROM SystemPermission\n                         WHERE SystemPermission.spToPersonUid = :accountPersonUid\n                           AND (SystemPermission.spPermissionsFlag & \n    \n                  128\n                  \n        ) > 0)\n               )\n    \n               ) AS hasLearningRecordPermission\n          FROM Clazz\n         WHERE Clazz.clazzUid = :clazzUid\n           AND (  (\n             /* If the accountPersonUid is the owner of the course, all permissions are granted */\n             (COALESCE(\n                          (SELECT _Clazz_Permission.clazzOwnerPersonUid \n                             FROM Clazz _Clazz_Permission\n                            WHERE _Clazz_Permission.clazzUid = :clazzUid), 0) = :accountPersonUid)\n              /* \n              If there is a CoursePermission entity that is for the course as per the clazzUid\n              parameter that is granted to the person directly or to the enrolmentRole that the \n              person has in the course, then permission is granted.\n              */              \n              OR EXISTS(SELECT CoursePermission.cpUid\n                          FROM CoursePermission\n                               \n        LEFT JOIN ClazzEnrolment ClazzEnrolment_ForAccountPerson \n                        ON CoursePermission.cpToEnrolmentRole != 0\n                       AND ClazzEnrolment_ForAccountPerson.clazzEnrolmentUid = \n                           (SELECT COALESCE(\n                                   (SELECT _ClazzEnrolment_AccountPersonInner.clazzEnrolmentUid \n                                      FROM ClazzEnrolment _ClazzEnrolment_AccountPersonInner\n                                     WHERE _ClazzEnrolment_AccountPersonInner.clazzEnrolmentClazzUid = CoursePermission.cpClazzUid\n                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentPersonUid = :accountPersonUid\n                                       AND _ClazzEnrolment_AccountPersonInner.clazzEnrolmentActive\n                                  ORDER BY _ClazzEnrolment_AccountPersonInner.clazzEnrolmentDateLeft DESC   \n                                     LIMIT 1), 0))\n    \n                         WHERE CoursePermission.cpClazzUid = :clazzUid\n                           AND (CoursePermission.cpToPersonUid = :accountPersonUid \n                                OR CoursePermission.cpToEnrolmentRole = ClazzEnrolment_ForAccountPerson.clazzEnrolmentRole)\n                           AND (CoursePermission.cpPermissionsFlag & \n         \n                  1\n                  \n        ) > 0)\n              OR EXISTS(SELECT SystemPermission.spUid\n                          FROM SystemPermission\n                         WHERE SystemPermission.spToPersonUid = :accountPersonUid\n                           AND (SystemPermission.spPermissionsFlag & \n    \n                  1\n                  \n        ) > 0)\n               )\n    \n               )\n    ")
  public actual abstract fun clazzAndDetailPermissionsAsFlow(accountPersonUid: Long,
      clazzUid: Long): Flow<ClazzAndDetailPermissions?>

  @Query(`value` =
      "\n        SELECT Clazz.*, \n               CoursePicture.*,\n               (SELECT COUNT(DISTINCT ClazzEnrolment.clazzEnrolmentPersonUid) \n                  FROM ClazzEnrolment \n                 WHERE ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid \n                   AND clazzEnrolmentRole = 1000 \n                   AND :currentTime BETWEEN ClazzEnrolment.clazzEnrolmentDateJoined \n                        AND ClazzEnrolment.clazzEnrolmentDateLeft) AS numStudents,\n               (SELECT COUNT(DISTINCT ClazzEnrolment.clazzEnrolmentPersonUid) \n                  FROM ClazzEnrolment \n                 WHERE ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid \n                   AND clazzEnrolmentRole = 1001 \n                   AND :currentTime BETWEEN ClazzEnrolment.clazzEnrolmentDateJoined \n                       AND ClazzEnrolment.clazzEnrolmentDateLeft) AS numTeachers,\n                CourseTerminology.*,\n                (SELECT EXISTS(\n                        SELECT 1\n                          FROM ClazzEnrolment\n                         WHERE ClazzEnrolment.clazzEnrolmentClazzUid = :clazzUid\n                           AND ClazzEnrolment.clazzEnrolmentPersonUid = :accountPersonUid\n                           AND ClazzEnrolment.clazzEnrolmentRole = 1000\n)\n                ) AS activeUserIsStudent\n         FROM Clazz \n              LEFT JOIN CourseTerminology\n                        ON CourseTerminology.ctUid = Clazz.clazzTerminologyUid\n              LEFT JOIN CoursePicture\n                        ON CoursePicture.coursePictureUid = :clazzUid\n        WHERE Clazz.clazzUid = :clazzUid")
  public actual abstract fun getClazzWithDisplayDetails(
    clazzUid: Long,
    currentTime: Long,
    accountPersonUid: Long,
  ): Flow<ClazzAndDisplayDetails?>

  @Query(`value` =
      "\n        SELECT Clazz.*, \n               HolidayCalendar.*,\n               CourseTerminology.*,\n               CoursePicture.*\n         FROM Clazz \n              LEFT JOIN HolidayCalendar \n              ON ((clazz.clazzHolidayUMCalendarUid != 0 \n                AND HolidayCalendar.umCalendarUid = clazz.clazzHolidayUMCalendarUid)\n                OR clazz.clazzHolidayUMCalendarUid = 0 AND clazz.clazzSchoolUid = 0 \n                AND HolidayCalendar.umCalendarUid = 0) \n              LEFT JOIN CourseTerminology\n              ON CourseTerminology.ctUid = Clazz.clazzTerminologyUid\n              \n              LEFT JOIN CoursePicture\n                        ON CoursePicture.coursePictureUid = 0\n                \n        WHERE :filterUid = 0 \n           OR Clazz.clazzUid = :filterUid\n    ")
  public actual abstract fun findClazzesWithEffectiveHolidayCalendarAndFilter(filterUid: Long):
      List<ClazzWithHolidayCalendarAndAndTerminology>

  @Query(`value` =
      "\n        SELECT Clazz.clazzName\n          FROM Clazz\n         WHERE Clazz.clazzUid = :clazzUid\n    ")
  public actual abstract fun getTitleByUidAsFlow(clazzUid: Long): Flow<String?>

  @Query(`value` =
      "\n        SELECT Clazz.clazzName AS clazzName,\n               CourseTerminology.*\n          FROM Clazz\n               LEFT JOIN CourseTerminology\n                         ON CourseTerminology.ctUid = Clazz.clazzTerminologyUid\n         WHERE Clazz.clazzUid = :clazzUid                \n    ")
  public actual abstract fun getClazzNameAndTerminologyAsFlow(clazzUid: Long):
      Flow<ClazzNameAndTerminology?>

  @Query(`value` =
      "\n        SELECT Clazz.clazzName AS clazzName\n          FROM Clazz\n         WHERE Clazz.clazzUid = :clazzUid                \n    ")
  public actual abstract fun getClazzNameAsFlow(clazzUid: Long): Flow<String?>

  @Query(`value` =
      "\n        SELECT Clazz.clazzTimeZone\n          FROM Clazz\n         WHERE Clazz.clazzUid = :clazzUid \n    ")
  public actual abstract suspend fun getClazzTimeZoneByClazzUidAsync(clazzUid: Long): String?

  @Query(`value` =
      "\n        SELECT Clazz.*\n          FROM Clazz\n         WHERE Clazz.clazzName IN (:names) \n    ")
  public actual abstract suspend fun getCoursesByName(names: List<String>): List<Clazz>

  @Query(`value` =
      "\n        SELECT Clazz.*\n          FROM CLAZZ\n               LEFT JOIN ClazzEnrolment \n                    ON ClazzEnrolment.clazzEnrolmentUid =\n                       COALESCE(\n                       (SELECT ClazzEnrolment.clazzEnrolmentUid \n                          FROM ClazzEnrolment\n                         WHERE ClazzEnrolment.clazzEnrolmentPersonUid = :accountPersonUid\n                           AND ClazzEnrolment.clazzEnrolmentActive\n                           AND ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid \n                      ORDER BY ClazzEnrolment.clazzEnrolmentDateLeft DESC   \n                         LIMIT 1), 0)\n          WHERE (   Clazz.clazzOwnerPersonUid = :accountPersonUid\n                 OR EXISTS(SELECT CoursePermission.cpUid\n                             FROM CoursePermission\n                            WHERE CoursePermission.cpClazzUid = Clazz.clazzUid\n                              AND (   CoursePermission.cpToPersonUid = :accountPersonUid \n                                   OR CoursePermission.cpToEnrolmentRole = ClazzEnrolment.clazzEnrolmentRole )\n                              AND (CoursePermission.cpPermissionsFlag & 1) > 0 \n                              AND NOT CoursePermission.cpIsDeleted)   \n                 OR (\n        EXISTS(SELECT 1\n                 FROM SystemPermission\n                WHERE :accountPersonUid != 0 \n                  AND SystemPermission.spToPersonUid = :accountPersonUid\n                  AND (SystemPermission.spPermissionsFlag &\n    \n                     1\n                     \n        ) > 0\n                  AND NOT SystemPermission.spIsDeleted)\n    \n                    )             \n                )\n           AND EXISTS \n                (SELECT ClazzEnrolment.clazzEnrolmentUid\n                   FROM ClazzEnrolment\n                  WHERE ClazzEnrolment.clazzEnrolmentPersonUid = :filterByEnrolledMemberPersonUid\n                    AND ClazzEnrolment.clazzEnrolmentClazzUid = Clazz.clazzUid\n                )  \n    ")
  public actual abstract suspend fun findOneRosterUserClazzes(accountPersonUid: Long,
      filterByEnrolledMemberPersonUid: Long): List<Clazz>
}
