package com.ustadmobile.core.db.dao;

import android.database.Cursor;
import androidx.paging.DataSource;
import androidx.room.CoroutinesRoom;
import androidx.room.EntityDeletionOrUpdateAdapter;
import androidx.room.EntityInsertionAdapter;
import androidx.room.RoomDatabase;
import androidx.room.RoomSQLiteQuery;
import androidx.room.SharedSQLiteStatement;
import androidx.room.paging.LimitOffsetDataSource;
import androidx.room.util.CursorUtil;
import androidx.room.util.DBUtil;
import androidx.sqlite.db.SupportSQLiteStatement;
import com.ustadmobile.lib.db.entities.LearnerGroup;
import java.lang.Class;
import java.lang.Exception;
import java.lang.Integer;
import java.lang.Long;
import java.lang.Object;
import java.lang.Override;
import java.lang.String;
import java.lang.SuppressWarnings;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import kotlin.Unit;
import kotlin.coroutines.Continuation;

@SuppressWarnings({"unchecked", "deprecation"})
public final class LearnerGroupDao_Impl extends LearnerGroupDao {
  private final RoomDatabase __db;

  private final EntityInsertionAdapter<LearnerGroup> __insertionAdapterOfLearnerGroup;

  private final EntityDeletionOrUpdateAdapter<LearnerGroup> __updateAdapterOfLearnerGroup;

  private final SharedSQLiteStatement __preparedStmtOfReplicateOnNewNode;

  private final SharedSQLiteStatement __preparedStmtOfReplicateOnChange;

  public LearnerGroupDao_Impl(RoomDatabase __db) {
    this.__db = __db;
    this.__insertionAdapterOfLearnerGroup = new EntityInsertionAdapter<LearnerGroup>(__db) {
      @Override
      public String createQuery() {
        return "INSERT OR ABORT INTO `LearnerGroup` (`learnerGroupUid`,`learnerGroupName`,`learnerGroupDescription`,`learnerGroupActive`,`learnerGroupMCSN`,`learnerGroupCSN`,`learnerGroupLCB`,`learnerGroupLct`) VALUES (nullif(?, 0),?,?,?,?,?,?,?)";
      }

      @Override
      public void bind(SupportSQLiteStatement stmt, LearnerGroup value) {
        stmt.bindLong(1, value.getLearnerGroupUid());
        if (value.getLearnerGroupName() == null) {
          stmt.bindNull(2);
        } else {
          stmt.bindString(2, value.getLearnerGroupName());
        }
        if (value.getLearnerGroupDescription() == null) {
          stmt.bindNull(3);
        } else {
          stmt.bindString(3, value.getLearnerGroupDescription());
        }
        final int _tmp = value.getLearnerGroupActive() ? 1 : 0;
        stmt.bindLong(4, _tmp);
        stmt.bindLong(5, value.getLearnerGroupMCSN());
        stmt.bindLong(6, value.getLearnerGroupCSN());
        stmt.bindLong(7, value.getLearnerGroupLCB());
        stmt.bindLong(8, value.getLearnerGroupLct());
      }
    };
    this.__updateAdapterOfLearnerGroup = new EntityDeletionOrUpdateAdapter<LearnerGroup>(__db) {
      @Override
      public String createQuery() {
        return "UPDATE OR ABORT `LearnerGroup` SET `learnerGroupUid` = ?,`learnerGroupName` = ?,`learnerGroupDescription` = ?,`learnerGroupActive` = ?,`learnerGroupMCSN` = ?,`learnerGroupCSN` = ?,`learnerGroupLCB` = ?,`learnerGroupLct` = ? WHERE `learnerGroupUid` = ?";
      }

      @Override
      public void bind(SupportSQLiteStatement stmt, LearnerGroup value) {
        stmt.bindLong(1, value.getLearnerGroupUid());
        if (value.getLearnerGroupName() == null) {
          stmt.bindNull(2);
        } else {
          stmt.bindString(2, value.getLearnerGroupName());
        }
        if (value.getLearnerGroupDescription() == null) {
          stmt.bindNull(3);
        } else {
          stmt.bindString(3, value.getLearnerGroupDescription());
        }
        final int _tmp = value.getLearnerGroupActive() ? 1 : 0;
        stmt.bindLong(4, _tmp);
        stmt.bindLong(5, value.getLearnerGroupMCSN());
        stmt.bindLong(6, value.getLearnerGroupCSN());
        stmt.bindLong(7, value.getLearnerGroupLCB());
        stmt.bindLong(8, value.getLearnerGroupLct());
        stmt.bindLong(9, value.getLearnerGroupUid());
      }
    };
    this.__preparedStmtOfReplicateOnNewNode = new SharedSQLiteStatement(__db) {
      @Override
      public String createQuery() {
        final String _query = "\n"
                + "     REPLACE INTO LearnerGroupReplicate(lgPk, lgDestination)\n"
                + "      SELECT DISTINCT LearnerGroup.learnerGroupUid AS lgPk,\n"
                + "             ? AS lgDestination\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"
                + "                  64\n"
                + "                  \n"
                + "                                                    ) > 0\n"
                + "            JOIN Person \n"
                + "                 ON \n"
                + "                ((ScopedGrant.sgTableId = -2\n"
                + "                    AND ScopedGrant.sgEntityUid = -2)\n"
                + "                 OR (ScopedGrant.sgTableId = 9\n"
                + "                    AND ScopedGrant.sgEntityUid = Person.personUid)\n"
                + "                 OR (ScopedGrant.sgTableId = 6       \n"
                + "                    AND Person.personUid IN (\n"
                + "                        SELECT DISTINCT clazzEnrolmentPersonUid\n"
                + "                          FROM ClazzEnrolment\n"
                + "                         WHERE clazzEnrolmentClazzUid =ScopedGrant.sgEntityUid \n"
                + "                           AND ClazzEnrolment.clazzEnrolmentActive))\n"
                + "                 OR (ScopedGrant.sgTableId = 164\n"
                + "                    AND Person.personUid IN (\n"
                + "                        SELECT DISTINCT schoolMemberPersonUid\n"
                + "                          FROM SchoolMember\n"
                + "                         WHERE schoolMemberSchoolUid = ScopedGrant.sgEntityUid\n"
                + "                           AND schoolMemberActive))\n"
                + "                           )    \n"
                + "        \n"
                + "        \n"
                + "             JOIN LearnerGroupMember\n"
                + "                  ON LearnerGroupMember.learnerGroupMemberPersonUid = Person.personUid\n"
                + "             JOIN LearnerGroup\n"
                + "                  ON LearnerGroup.learnerGroupUid = LearnerGroupMember.learnerGroupMemberLgUid\n"
                + "            WHERE UserSession.usClientNodeId = ?\n"
                + "              AND UserSession.usStatus = 1\n"
                + "              AND LearnerGroup.learnerGroupLct != COALESCE(\n"
                + "                  (SELECT lgVersionId\n"
                + "                     FROM LearnerGroupReplicate\n"
                + "                    WHERE lgPk = LearnerGroup.learnerGroupUid\n"
                + "                      AND lgDestination = ?), 0) \n"
                + "      /*psql ON CONFLICT(lgPk, lgDestination) DO UPDATE\n"
                + "             SET lgPending = true\n"
                + "      */       \n"
                + " ";
        return _query;
      }
    };
    this.__preparedStmtOfReplicateOnChange = new SharedSQLiteStatement(__db) {
      @Override
      public String createQuery() {
        final String _query = "\n"
                + " REPLACE INTO LearnerGroupReplicate(lgPk, lgDestination)\n"
                + "  SELECT DISTINCT LearnerGroup.learnerGroupUid AS lgUid,\n"
                + "         UserSession.usClientNodeId AS lgDestination\n"
                + "    FROM ChangeLog\n"
                + "         JOIN LearnerGroup\n"
                + "              ON ChangeLog.chTableId = 301\n"
                + "                 AND ChangeLog.chEntityPk = LearnerGroup.learnerGroupUid\n"
                + "         JOIN LearnerGroupMember\n"
                + "              ON LearnerGroupMember.learnerGroupMemberLgUid = LearnerGroup.learnerGroupUid\n"
                + "         JOIN Person\n"
                + "              ON Person.personUid = LearnerGroupMember.learnerGroupMemberPersonUid\n"
                + "         \n"
                + "            JOIN ScopedGrant \n"
                + "                   ON \n"
                + "            ((ScopedGrant.sgTableId = -2\n"
                + "                    AND ScopedGrant.sgEntityUid = -2)\n"
                + "                 OR (ScopedGrant.sgTableId = 9\n"
                + "                    AND ScopedGrant.sgEntityUid = Person.personUid)\n"
                + "                 OR (ScopedGrant.sgTableId = 6       \n"
                + "                    AND ScopedGrant.sgEntityUid IN (\n"
                + "                        SELECT DISTINCT clazzEnrolmentClazzUid\n"
                + "                          FROM ClazzEnrolment\n"
                + "                         WHERE clazzEnrolmentPersonUid = Person.personUid \n"
                + "                           AND ClazzEnrolment.clazzEnrolmentActive))\n"
                + "                 OR (ScopedGrant.sgTableId = 164\n"
                + "                    AND ScopedGrant.sgEntityUid IN (\n"
                + "                        SELECT DISTINCT schoolMemberSchoolUid\n"
                + "                          FROM SchoolMember\n"
                + "                         WHERE schoolMemberPersonUid = Person.personUid\n"
                + "                           AND schoolMemberActive))\n"
                + "                           )\n"
                + "        \n"
                + "                   AND (ScopedGrant.sgPermissions & \n"
                + "        \n"
                + "              64\n"
                + "              \n"
                + "                                                     ) > 0\n"
                + "             JOIN PersonGroupMember AS PrsGrpMbr\n"
                + "                   ON ScopedGrant.sgGroupUid = PrsGrpMbr.groupMemberGroupUid\n"
                + "              JOIN UserSession\n"
                + "                   ON UserSession.usPersonUid = PrsGrpMbr.groupMemberPersonUid\n"
                + "                      AND UserSession.usStatus = 1\n"
                + "        \n"
                + " /*psql ON CONFLICT(lgPk, lgDestination) DO UPDATE\n"
                + "     SET lgPending = true\n"
                + "  */               \n"
                + "    ";
        return _query;
      }
    };
  }

  @Override
  public long insert(final LearnerGroup entity) {
    __db.assertNotSuspendingTransaction();
    __db.beginTransaction();
    try {
      long _result = __insertionAdapterOfLearnerGroup.insertAndReturnId(entity);
      __db.setTransactionSuccessful();
      return _result;
    } finally {
      __db.endTransaction();
    }
  }

  @Override
  public Object insertAsync(final LearnerGroup entity,
      final Continuation<? super Long> continuation) {
    return CoroutinesRoom.execute(__db, true, new Callable<Long>() {
      @Override
      public Long call() throws Exception {
        __db.beginTransaction();
        try {
          long _result = __insertionAdapterOfLearnerGroup.insertAndReturnId(entity);
          __db.setTransactionSuccessful();
          return _result;
        } finally {
          __db.endTransaction();
        }
      }
    }, continuation);
  }

  @Override
  public void insertList(final List<? extends LearnerGroup> entityList) {
    __db.assertNotSuspendingTransaction();
    __db.beginTransaction();
    try {
      __insertionAdapterOfLearnerGroup.insert(entityList);
      __db.setTransactionSuccessful();
    } finally {
      __db.endTransaction();
    }
  }

  @Override
  public void updateList(final List<? extends LearnerGroup> entityList) {
    __db.assertNotSuspendingTransaction();
    __db.beginTransaction();
    try {
      __updateAdapterOfLearnerGroup.handleMultiple(entityList);
      __db.setTransactionSuccessful();
    } finally {
      __db.endTransaction();
    }
  }

  @Override
  public void update(final LearnerGroup entity) {
    __db.assertNotSuspendingTransaction();
    __db.beginTransaction();
    try {
      __updateAdapterOfLearnerGroup.handle(entity);
      __db.setTransactionSuccessful();
    } finally {
      __db.endTransaction();
    }
  }

  @Override
  public Object replicateOnNewNode(final long newNodeId,
      final Continuation<? super Unit> continuation) {
    return CoroutinesRoom.execute(__db, true, new Callable<Unit>() {
      @Override
      public Unit call() throws Exception {
        final SupportSQLiteStatement _stmt = __preparedStmtOfReplicateOnNewNode.acquire();
        int _argIndex = 1;
        _stmt.bindLong(_argIndex, newNodeId);
        _argIndex = 2;
        _stmt.bindLong(_argIndex, newNodeId);
        _argIndex = 3;
        _stmt.bindLong(_argIndex, newNodeId);
        __db.beginTransaction();
        try {
          _stmt.executeInsert();
          __db.setTransactionSuccessful();
          return Unit.INSTANCE;
        } finally {
          __db.endTransaction();
          __preparedStmtOfReplicateOnNewNode.release(_stmt);
        }
      }
    }, continuation);
  }

  @Override
  public Object replicateOnChange(final Continuation<? super Unit> continuation) {
    return CoroutinesRoom.execute(__db, true, new Callable<Unit>() {
      @Override
      public Unit call() throws Exception {
        final SupportSQLiteStatement _stmt = __preparedStmtOfReplicateOnChange.acquire();
        __db.beginTransaction();
        try {
          _stmt.executeInsert();
          __db.setTransactionSuccessful();
          return Unit.INSTANCE;
        } finally {
          __db.endTransaction();
          __preparedStmtOfReplicateOnChange.release(_stmt);
        }
      }
    }, continuation);
  }

  @Override
  public DataSource.Factory<Integer, LearnerGroup> findGroupsForEntryAsync(
      final long contentEntryUid) {
    final String _sql = "SELECT LearnerGroup.* FROM LearnerGroup \n"
            + "            LEFT JOIN GroupLearningSession ON \n"
            + "            GroupLearningSession.groupLearningSessionLearnerGroupUid = LearnerGroup.learnerGroupUid \n"
            + "            WHERE GroupLearningSession.groupLearningSessionContentUid = ?";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
    int _argIndex = 1;
    _statement.bindLong(_argIndex, contentEntryUid);
    return new DataSource.Factory<Integer, LearnerGroup>() {
      @Override
      public LimitOffsetDataSource<LearnerGroup> create() {
        return new LimitOffsetDataSource<LearnerGroup>(__db, _statement, false, true , "LearnerGroup", "GroupLearningSession") {
          @Override
          protected List<LearnerGroup> convertRows(Cursor cursor) {
            final int _cursorIndexOfLearnerGroupUid = CursorUtil.getColumnIndexOrThrow(cursor, "learnerGroupUid");
            final int _cursorIndexOfLearnerGroupName = CursorUtil.getColumnIndexOrThrow(cursor, "learnerGroupName");
            final int _cursorIndexOfLearnerGroupDescription = CursorUtil.getColumnIndexOrThrow(cursor, "learnerGroupDescription");
            final int _cursorIndexOfLearnerGroupActive = CursorUtil.getColumnIndexOrThrow(cursor, "learnerGroupActive");
            final int _cursorIndexOfLearnerGroupMCSN = CursorUtil.getColumnIndexOrThrow(cursor, "learnerGroupMCSN");
            final int _cursorIndexOfLearnerGroupCSN = CursorUtil.getColumnIndexOrThrow(cursor, "learnerGroupCSN");
            final int _cursorIndexOfLearnerGroupLCB = CursorUtil.getColumnIndexOrThrow(cursor, "learnerGroupLCB");
            final int _cursorIndexOfLearnerGroupLct = CursorUtil.getColumnIndexOrThrow(cursor, "learnerGroupLct");
            final List<LearnerGroup> _res = new ArrayList<LearnerGroup>(cursor.getCount());
            while(cursor.moveToNext()) {
              final LearnerGroup _item;
              _item = new LearnerGroup();
              final long _tmpLearnerGroupUid;
              _tmpLearnerGroupUid = cursor.getLong(_cursorIndexOfLearnerGroupUid);
              _item.setLearnerGroupUid(_tmpLearnerGroupUid);
              final String _tmpLearnerGroupName;
              if (cursor.isNull(_cursorIndexOfLearnerGroupName)) {
                _tmpLearnerGroupName = null;
              } else {
                _tmpLearnerGroupName = cursor.getString(_cursorIndexOfLearnerGroupName);
              }
              _item.setLearnerGroupName(_tmpLearnerGroupName);
              final String _tmpLearnerGroupDescription;
              if (cursor.isNull(_cursorIndexOfLearnerGroupDescription)) {
                _tmpLearnerGroupDescription = null;
              } else {
                _tmpLearnerGroupDescription = cursor.getString(_cursorIndexOfLearnerGroupDescription);
              }
              _item.setLearnerGroupDescription(_tmpLearnerGroupDescription);
              final boolean _tmpLearnerGroupActive;
              final int _tmp;
              _tmp = cursor.getInt(_cursorIndexOfLearnerGroupActive);
              _tmpLearnerGroupActive = _tmp != 0;
              _item.setLearnerGroupActive(_tmpLearnerGroupActive);
              final long _tmpLearnerGroupMCSN;
              _tmpLearnerGroupMCSN = cursor.getLong(_cursorIndexOfLearnerGroupMCSN);
              _item.setLearnerGroupMCSN(_tmpLearnerGroupMCSN);
              final long _tmpLearnerGroupCSN;
              _tmpLearnerGroupCSN = cursor.getLong(_cursorIndexOfLearnerGroupCSN);
              _item.setLearnerGroupCSN(_tmpLearnerGroupCSN);
              final int _tmpLearnerGroupLCB;
              _tmpLearnerGroupLCB = cursor.getInt(_cursorIndexOfLearnerGroupLCB);
              _item.setLearnerGroupLCB(_tmpLearnerGroupLCB);
              final long _tmpLearnerGroupLct;
              _tmpLearnerGroupLct = cursor.getLong(_cursorIndexOfLearnerGroupLct);
              _item.setLearnerGroupLct(_tmpLearnerGroupLct);
              _res.add(_item);
            }
            return _res;
          }
        };
      }
    };
  }

  @Override
  public List<LearnerGroup> findGroupListForEntry(final long contentEntryUid) {
    final String _sql = "SELECT LearnerGroup.* FROM LearnerGroup \n"
            + "            LEFT JOIN GroupLearningSession ON \n"
            + "            GroupLearningSession.groupLearningSessionLearnerGroupUid = LearnerGroup.learnerGroupUid \n"
            + "            WHERE GroupLearningSession.groupLearningSessionContentUid = ?";
    final RoomSQLiteQuery _statement = RoomSQLiteQuery.acquire(_sql, 1);
    int _argIndex = 1;
    _statement.bindLong(_argIndex, contentEntryUid);
    __db.assertNotSuspendingTransaction();
    final Cursor _cursor = DBUtil.query(__db, _statement, false, null);
    try {
      final int _cursorIndexOfLearnerGroupUid = CursorUtil.getColumnIndexOrThrow(_cursor, "learnerGroupUid");
      final int _cursorIndexOfLearnerGroupName = CursorUtil.getColumnIndexOrThrow(_cursor, "learnerGroupName");
      final int _cursorIndexOfLearnerGroupDescription = CursorUtil.getColumnIndexOrThrow(_cursor, "learnerGroupDescription");
      final int _cursorIndexOfLearnerGroupActive = CursorUtil.getColumnIndexOrThrow(_cursor, "learnerGroupActive");
      final int _cursorIndexOfLearnerGroupMCSN = CursorUtil.getColumnIndexOrThrow(_cursor, "learnerGroupMCSN");
      final int _cursorIndexOfLearnerGroupCSN = CursorUtil.getColumnIndexOrThrow(_cursor, "learnerGroupCSN");
      final int _cursorIndexOfLearnerGroupLCB = CursorUtil.getColumnIndexOrThrow(_cursor, "learnerGroupLCB");
      final int _cursorIndexOfLearnerGroupLct = CursorUtil.getColumnIndexOrThrow(_cursor, "learnerGroupLct");
      final List<LearnerGroup> _result = new ArrayList<LearnerGroup>(_cursor.getCount());
      while(_cursor.moveToNext()) {
        final LearnerGroup _item;
        _item = new LearnerGroup();
        final long _tmpLearnerGroupUid;
        _tmpLearnerGroupUid = _cursor.getLong(_cursorIndexOfLearnerGroupUid);
        _item.setLearnerGroupUid(_tmpLearnerGroupUid);
        final String _tmpLearnerGroupName;
        if (_cursor.isNull(_cursorIndexOfLearnerGroupName)) {
          _tmpLearnerGroupName = null;
        } else {
          _tmpLearnerGroupName = _cursor.getString(_cursorIndexOfLearnerGroupName);
        }
        _item.setLearnerGroupName(_tmpLearnerGroupName);
        final String _tmpLearnerGroupDescription;
        if (_cursor.isNull(_cursorIndexOfLearnerGroupDescription)) {
          _tmpLearnerGroupDescription = null;
        } else {
          _tmpLearnerGroupDescription = _cursor.getString(_cursorIndexOfLearnerGroupDescription);
        }
        _item.setLearnerGroupDescription(_tmpLearnerGroupDescription);
        final boolean _tmpLearnerGroupActive;
        final int _tmp;
        _tmp = _cursor.getInt(_cursorIndexOfLearnerGroupActive);
        _tmpLearnerGroupActive = _tmp != 0;
        _item.setLearnerGroupActive(_tmpLearnerGroupActive);
        final long _tmpLearnerGroupMCSN;
        _tmpLearnerGroupMCSN = _cursor.getLong(_cursorIndexOfLearnerGroupMCSN);
        _item.setLearnerGroupMCSN(_tmpLearnerGroupMCSN);
        final long _tmpLearnerGroupCSN;
        _tmpLearnerGroupCSN = _cursor.getLong(_cursorIndexOfLearnerGroupCSN);
        _item.setLearnerGroupCSN(_tmpLearnerGroupCSN);
        final int _tmpLearnerGroupLCB;
        _tmpLearnerGroupLCB = _cursor.getInt(_cursorIndexOfLearnerGroupLCB);
        _item.setLearnerGroupLCB(_tmpLearnerGroupLCB);
        final long _tmpLearnerGroupLct;
        _tmpLearnerGroupLct = _cursor.getLong(_cursorIndexOfLearnerGroupLct);
        _item.setLearnerGroupLct(_tmpLearnerGroupLct);
        _result.add(_item);
      }
      return _result;
    } finally {
      _cursor.close();
      _statement.release();
    }
  }

  public static List<Class<?>> getRequiredConverters() {
    return Collections.emptyList();
  }
}
