package com.ustadmobile.core.db.dao;

import androidx.room.CoroutinesRoom;
import androidx.room.EntityDeletionOrUpdateAdapter;
import androidx.room.EntityInsertionAdapter;
import androidx.room.RoomDatabase;
import androidx.room.SharedSQLiteStatement;
import androidx.sqlite.db.SupportSQLiteStatement;
import com.ustadmobile.lib.db.entities.MessageRead;
import java.lang.Class;
import java.lang.Exception;
import java.lang.Long;
import java.lang.Object;
import java.lang.Override;
import java.lang.String;
import java.lang.SuppressWarnings;
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 MessageReadDao_Impl extends MessageReadDao {
  private final RoomDatabase __db;

  private final EntityInsertionAdapter<MessageRead> __insertionAdapterOfMessageRead;

  private final EntityDeletionOrUpdateAdapter<MessageRead> __updateAdapterOfMessageRead;

  private final SharedSQLiteStatement __preparedStmtOfReplicateOnNewNodeChats;

  private final SharedSQLiteStatement __preparedStmtOfReplicateOnChange;

  public MessageReadDao_Impl(RoomDatabase __db) {
    this.__db = __db;
    this.__insertionAdapterOfMessageRead = new EntityInsertionAdapter<MessageRead>(__db) {
      @Override
      public String createQuery() {
        return "INSERT OR ABORT INTO `MessageRead` (`messageReadUid`,`messageReadPersonUid`,`messageReadMessageUid`,`messageReadEntityUid`,`messageReadLct`) VALUES (nullif(?, 0),?,?,?,?)";
      }

      @Override
      public void bind(SupportSQLiteStatement stmt, MessageRead value) {
        stmt.bindLong(1, value.getMessageReadUid());
        stmt.bindLong(2, value.getMessageReadPersonUid());
        stmt.bindLong(3, value.getMessageReadMessageUid());
        stmt.bindLong(4, value.getMessageReadEntityUid());
        stmt.bindLong(5, value.getMessageReadLct());
      }
    };
    this.__updateAdapterOfMessageRead = new EntityDeletionOrUpdateAdapter<MessageRead>(__db) {
      @Override
      public String createQuery() {
        return "UPDATE OR ABORT `MessageRead` SET `messageReadUid` = ?,`messageReadPersonUid` = ?,`messageReadMessageUid` = ?,`messageReadEntityUid` = ?,`messageReadLct` = ? WHERE `messageReadUid` = ?";
      }

      @Override
      public void bind(SupportSQLiteStatement stmt, MessageRead value) {
        stmt.bindLong(1, value.getMessageReadUid());
        stmt.bindLong(2, value.getMessageReadPersonUid());
        stmt.bindLong(3, value.getMessageReadMessageUid());
        stmt.bindLong(4, value.getMessageReadEntityUid());
        stmt.bindLong(5, value.getMessageReadLct());
        stmt.bindLong(6, value.getMessageReadUid());
      }
    };
    this.__preparedStmtOfReplicateOnNewNodeChats = new SharedSQLiteStatement(__db) {
      @Override
      public String createQuery() {
        final String _query = "\n"
                + "     REPLACE INTO MessageReadReplicate(messageReadPk, messageReadDestination)\n"
                + "      SELECT DISTINCT MessageRead.messageReadUid AS messageReadPk,\n"
                + "             ? AS messageReadDestination\n"
                + "        FROM UserSession \n"
                + "              JOIN Message ON\n"
                + "                  ((    Message.messageTableId = 127\n"
                + "                    AND Message.messageEntityUid IN\n"
                + "                        (SELECT ChatMember.chatMemberChatUid \n"
                + "                          FROM ChatMember\n"
                + "                         WHERE ChatMember.chatMemberPersonUid = UserSession.usPersonUid))\n"
                + "                  OR UserSession.usSessionType = 2)\n"
                + "                  \n"
                + "              JOIN MessageRead \n"
                + "                   ON MessageRead.messageReadMessageUid = Message.messageUid\n"
                + "                   \n"
                + "       WHERE UserSession.usClientNodeId = ?\n"
                + "         AND UserSession.usStatus = 1\n"
                + "         AND MessageRead.messageReadLct != COALESCE(\n"
                + "             (SELECT messageReadVersionId\n"
                + "                FROM MessageReadReplicate\n"
                + "               WHERE messageReadPk = MessageRead.messageReadUid\n"
                + "                 AND messageReadDestination = ?), 0) \n"
                + "      /*psql ON CONFLICT(messageReadPk, messageReadDestination) DO UPDATE\n"
                + "             SET messageReadPending = true\n"
                + "      */       \n"
                + "    ";
        return _query;
      }
    };
    this.__preparedStmtOfReplicateOnChange = new SharedSQLiteStatement(__db) {
      @Override
      public String createQuery() {
        final String _query = "\n"
                + "         REPLACE INTO MessageReadReplicate(messageReadPk, messageReadDestination)\n"
                + "          SELECT DISTINCT MessageRead.messageReadUid AS messageReadUid,\n"
                + "                 UserSession.usClientNodeId AS messageReadDestination\n"
                + "            FROM ChangeLog\n"
                + "            \n"
                + "                 JOIN MessageRead \n"
                + "                      ON MessageRead.messageReadUid = ChangeLog.chEntityPk\n"
                + "                         AND ChangeLog.chTableId = 129\n"
                + "                         \n"
                + "\n"
                + "                 JOIN UserSession ON\n"
                + "                      ((UserSession.usPersonUid IN \n"
                + "                           (SELECT ChatMember.chatMemberPersonUid\n"
                + "                              FROM ChatMember\n"
                + "                             WHERE ChatMember.chatMemberChatUid = MessageRead.messageReadEntityUid))\n"
                + "                       OR UserSession.usSessionType = 2)\n"
                + "                   \n"
                + "           WHERE UserSession.usStatus = 1\n"
                + "             AND UserSession.usClientNodeId != (\n"
                + "                 SELECT nodeClientId \n"
                + "                   FROM SyncNode\n"
                + "                  LIMIT 1)\n"
                + "             AND MessageRead.messageReadLct != COALESCE(\n"
                + "                 (SELECT messageReadVersionId\n"
                + "                    FROM MessageReadReplicate\n"
                + "                   WHERE messageReadPk = MessageRead.messageReadUid\n"
                + "                     AND messageReadDestination = UserSession.usClientNodeId), 0)\n"
                + "         /*psql ON CONFLICT(messageReadPk, messageReadDestination) DO UPDATE\n"
                + "             SET messageReadPending = true\n"
                + "          */               \n"
                + "    ";
        return _query;
      }
    };
  }

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

  @Override
  public Object insertAsync(final MessageRead 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 = __insertionAdapterOfMessageRead.insertAndReturnId(entity);
          __db.setTransactionSuccessful();
          return _result;
        } finally {
          __db.endTransaction();
        }
      }
    }, continuation);
  }

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

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

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

  @Override
  public Object replicateOnNewNodeChats(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 = __preparedStmtOfReplicateOnNewNodeChats.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();
          __preparedStmtOfReplicateOnNewNodeChats.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);
  }

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