package com.ustadmobile.libcache.db.dao

import androidx.room.EntityInsertAdapter
import androidx.room.RoomDatabase
import androidx.room.coroutines.createFlow
import androidx.room.util.getColumnIndexOrThrow
import androidx.room.util.getTotalChangedRows
import androidx.room.util.performSuspending
import androidx.sqlite.SQLiteStatement
import com.ustadmobile.libcache.db.entities.NeighborCache
import javax.`annotation`.processing.Generated
import kotlin.Int
import kotlin.Long
import kotlin.String
import kotlin.Suppress
import kotlin.Unit
import kotlin.collections.List
import kotlin.collections.MutableList
import kotlin.collections.mutableListOf
import kotlin.reflect.KClass
import kotlinx.coroutines.flow.Flow

@Generated(value = ["androidx.room.RoomProcessor"])
@Suppress(names = ["UNCHECKED_CAST", "DEPRECATION", "REDUNDANT_PROJECTION", "REMOVAL"])
public class NeighborCacheDao_Impl(
  __db: RoomDatabase,
) : NeighborCacheDao() {
  private val __db: RoomDatabase

  private val __insertAdapterOfNeighborCache: EntityInsertAdapter<NeighborCache>

  private val __insertAdapterOfNeighborCache_1: EntityInsertAdapter<NeighborCache>
  init {
    this.__db = __db
    this.__insertAdapterOfNeighborCache = object : EntityInsertAdapter<NeighborCache>() {
      protected override fun createQuery(): String = "INSERT OR REPLACE INTO `NeighborCache` (`neighborUid`,`neighborDeviceName`,`neighborIp`,`neighborUdpPort`,`neighborHttpPort`,`neighborDiscovered`,`neighborPingTime`,`neighborLastSeen`,`neighborStatus`) VALUES (?,?,?,?,?,?,?,?,?)"

      protected override fun bind(statement: SQLiteStatement, entity: NeighborCache) {
        statement.bindLong(1, entity.neighborUid)
        statement.bindText(2, entity.neighborDeviceName)
        statement.bindText(3, entity.neighborIp)
        statement.bindLong(4, entity.neighborUdpPort.toLong())
        statement.bindLong(5, entity.neighborHttpPort.toLong())
        statement.bindLong(6, entity.neighborDiscovered)
        statement.bindLong(7, entity.neighborPingTime.toLong())
        statement.bindLong(8, entity.neighborLastSeen)
        statement.bindLong(9, entity.neighborStatus.toLong())
      }
    }
    this.__insertAdapterOfNeighborCache_1 = object : EntityInsertAdapter<NeighborCache>() {
      protected override fun createQuery(): String = "INSERT OR IGNORE INTO `NeighborCache` (`neighborUid`,`neighborDeviceName`,`neighborIp`,`neighborUdpPort`,`neighborHttpPort`,`neighborDiscovered`,`neighborPingTime`,`neighborLastSeen`,`neighborStatus`) VALUES (?,?,?,?,?,?,?,?,?)"

      protected override fun bind(statement: SQLiteStatement, entity: NeighborCache) {
        statement.bindLong(1, entity.neighborUid)
        statement.bindText(2, entity.neighborDeviceName)
        statement.bindText(3, entity.neighborIp)
        statement.bindLong(4, entity.neighborUdpPort.toLong())
        statement.bindLong(5, entity.neighborHttpPort.toLong())
        statement.bindLong(6, entity.neighborDiscovered)
        statement.bindLong(7, entity.neighborPingTime.toLong())
        statement.bindLong(8, entity.neighborLastSeen)
        statement.bindLong(9, entity.neighborStatus.toLong())
      }
    }
  }

  public override suspend fun upsertAsync(neighborCache: NeighborCache): Unit = performSuspending(__db, false, true) { _connection ->
    __insertAdapterOfNeighborCache.insert(_connection, neighborCache)
  }

  public override suspend fun upsert(neighborCache: NeighborCache): Unit = performSuspending(__db, false, true) { _connection ->
    __insertAdapterOfNeighborCache.insert(_connection, neighborCache)
  }

  public override suspend fun insertOrIgnore(neighborCache: NeighborCache): Unit = performSuspending(__db, false, true) { _connection ->
    __insertAdapterOfNeighborCache_1.insert(_connection, neighborCache)
  }

  public override fun allNeighborsAsFlow(): Flow<List<NeighborCache>> {
    val _sql: String = """
        |
        |        SELECT NeighborCache.*
        |          FROM NeighborCache
        |         WHERE NeighborCache.neighborStatus = 1 
        |    
        """.trimMargin()
    return createFlow(__db, false, arrayOf("NeighborCache")) { _connection ->
      val _stmt: SQLiteStatement = _connection.prepare(_sql)
      try {
        val _columnIndexOfNeighborUid: Int = getColumnIndexOrThrow(_stmt, "neighborUid")
        val _columnIndexOfNeighborDeviceName: Int = getColumnIndexOrThrow(_stmt, "neighborDeviceName")
        val _columnIndexOfNeighborIp: Int = getColumnIndexOrThrow(_stmt, "neighborIp")
        val _columnIndexOfNeighborUdpPort: Int = getColumnIndexOrThrow(_stmt, "neighborUdpPort")
        val _columnIndexOfNeighborHttpPort: Int = getColumnIndexOrThrow(_stmt, "neighborHttpPort")
        val _columnIndexOfNeighborDiscovered: Int = getColumnIndexOrThrow(_stmt, "neighborDiscovered")
        val _columnIndexOfNeighborPingTime: Int = getColumnIndexOrThrow(_stmt, "neighborPingTime")
        val _columnIndexOfNeighborLastSeen: Int = getColumnIndexOrThrow(_stmt, "neighborLastSeen")
        val _columnIndexOfNeighborStatus: Int = getColumnIndexOrThrow(_stmt, "neighborStatus")
        val _result: MutableList<NeighborCache> = mutableListOf()
        while (_stmt.step()) {
          val _item: NeighborCache
          val _tmpNeighborUid: Long
          _tmpNeighborUid = _stmt.getLong(_columnIndexOfNeighborUid)
          val _tmpNeighborDeviceName: String
          _tmpNeighborDeviceName = _stmt.getText(_columnIndexOfNeighborDeviceName)
          val _tmpNeighborIp: String
          _tmpNeighborIp = _stmt.getText(_columnIndexOfNeighborIp)
          val _tmpNeighborUdpPort: Int
          _tmpNeighborUdpPort = _stmt.getLong(_columnIndexOfNeighborUdpPort).toInt()
          val _tmpNeighborHttpPort: Int
          _tmpNeighborHttpPort = _stmt.getLong(_columnIndexOfNeighborHttpPort).toInt()
          val _tmpNeighborDiscovered: Long
          _tmpNeighborDiscovered = _stmt.getLong(_columnIndexOfNeighborDiscovered)
          val _tmpNeighborPingTime: Int
          _tmpNeighborPingTime = _stmt.getLong(_columnIndexOfNeighborPingTime).toInt()
          val _tmpNeighborLastSeen: Long
          _tmpNeighborLastSeen = _stmt.getLong(_columnIndexOfNeighborLastSeen)
          val _tmpNeighborStatus: Int
          _tmpNeighborStatus = _stmt.getLong(_columnIndexOfNeighborStatus).toInt()
          _item = NeighborCache(_tmpNeighborUid,_tmpNeighborDeviceName,_tmpNeighborIp,_tmpNeighborUdpPort,_tmpNeighborHttpPort,_tmpNeighborDiscovered,_tmpNeighborPingTime,_tmpNeighborLastSeen,_tmpNeighborStatus)
          _result.add(_item)
        }
        _result
      } finally {
        _stmt.close()
      }
    }
  }

  public override suspend fun allNeighbors(): List<NeighborCache> {
    val _sql: String = """
        |
        |        SELECT NeighborCache.*
        |          FROM NeighborCache
        |    
        """.trimMargin()
    return performSuspending(__db, true, false) { _connection ->
      val _stmt: SQLiteStatement = _connection.prepare(_sql)
      try {
        val _columnIndexOfNeighborUid: Int = getColumnIndexOrThrow(_stmt, "neighborUid")
        val _columnIndexOfNeighborDeviceName: Int = getColumnIndexOrThrow(_stmt, "neighborDeviceName")
        val _columnIndexOfNeighborIp: Int = getColumnIndexOrThrow(_stmt, "neighborIp")
        val _columnIndexOfNeighborUdpPort: Int = getColumnIndexOrThrow(_stmt, "neighborUdpPort")
        val _columnIndexOfNeighborHttpPort: Int = getColumnIndexOrThrow(_stmt, "neighborHttpPort")
        val _columnIndexOfNeighborDiscovered: Int = getColumnIndexOrThrow(_stmt, "neighborDiscovered")
        val _columnIndexOfNeighborPingTime: Int = getColumnIndexOrThrow(_stmt, "neighborPingTime")
        val _columnIndexOfNeighborLastSeen: Int = getColumnIndexOrThrow(_stmt, "neighborLastSeen")
        val _columnIndexOfNeighborStatus: Int = getColumnIndexOrThrow(_stmt, "neighborStatus")
        val _result: MutableList<NeighborCache> = mutableListOf()
        while (_stmt.step()) {
          val _item: NeighborCache
          val _tmpNeighborUid: Long
          _tmpNeighborUid = _stmt.getLong(_columnIndexOfNeighborUid)
          val _tmpNeighborDeviceName: String
          _tmpNeighborDeviceName = _stmt.getText(_columnIndexOfNeighborDeviceName)
          val _tmpNeighborIp: String
          _tmpNeighborIp = _stmt.getText(_columnIndexOfNeighborIp)
          val _tmpNeighborUdpPort: Int
          _tmpNeighborUdpPort = _stmt.getLong(_columnIndexOfNeighborUdpPort).toInt()
          val _tmpNeighborHttpPort: Int
          _tmpNeighborHttpPort = _stmt.getLong(_columnIndexOfNeighborHttpPort).toInt()
          val _tmpNeighborDiscovered: Long
          _tmpNeighborDiscovered = _stmt.getLong(_columnIndexOfNeighborDiscovered)
          val _tmpNeighborPingTime: Int
          _tmpNeighborPingTime = _stmt.getLong(_columnIndexOfNeighborPingTime).toInt()
          val _tmpNeighborLastSeen: Long
          _tmpNeighborLastSeen = _stmt.getLong(_columnIndexOfNeighborLastSeen)
          val _tmpNeighborStatus: Int
          _tmpNeighborStatus = _stmt.getLong(_columnIndexOfNeighborStatus).toInt()
          _item = NeighborCache(_tmpNeighborUid,_tmpNeighborDeviceName,_tmpNeighborIp,_tmpNeighborUdpPort,_tmpNeighborHttpPort,_tmpNeighborDiscovered,_tmpNeighborPingTime,_tmpNeighborLastSeen,_tmpNeighborStatus)
          _result.add(_item)
        }
        _result
      } finally {
        _stmt.close()
      }
    }
  }

  public override suspend fun deleteAsync(neighborUid: Long) {
    val _sql: String = """
        |
        |        DELETE FROM NeighborCache
        |         WHERE neighborUid = ?
        |    
        """.trimMargin()
    return performSuspending(__db, false, true) { _connection ->
      val _stmt: SQLiteStatement = _connection.prepare(_sql)
      try {
        var _argIndex: Int = 1
        _stmt.bindLong(_argIndex, neighborUid)
        _stmt.step()
      } finally {
        _stmt.close()
      }
    }
  }

  public override suspend fun updateHttpPort(neighborUid: Long, httpPort: Int) {
    val _sql: String = """
        |
        |        UPDATE NeighborCache
        |           SET neighborHttpPort = ?
        |         WHERE neighborUid = ?
        |           AND neighborHttpPort != ?
        |    
        """.trimMargin()
    return performSuspending(__db, false, true) { _connection ->
      val _stmt: SQLiteStatement = _connection.prepare(_sql)
      try {
        var _argIndex: Int = 1
        _stmt.bindLong(_argIndex, httpPort.toLong())
        _argIndex = 2
        _stmt.bindLong(_argIndex, neighborUid)
        _argIndex = 3
        _stmt.bindLong(_argIndex, httpPort.toLong())
        _stmt.step()
      } finally {
        _stmt.close()
      }
    }
  }

  public override suspend fun updatePingTime(
    neighborUid: Long,
    pingTime: Int,
    timeNow: Long,
  ): Int {
    val _sql: String = """
        |
        |        UPDATE NeighborCache
        |           SET neighborPingTime = ?,
        |               neighborLastSeen = ?
        |         WHERE neighborUid = ?  
        |    
        """.trimMargin()
    return performSuspending(__db, false, true) { _connection ->
      val _stmt: SQLiteStatement = _connection.prepare(_sql)
      try {
        var _argIndex: Int = 1
        _stmt.bindLong(_argIndex, pingTime.toLong())
        _argIndex = 2
        _stmt.bindLong(_argIndex, timeNow)
        _argIndex = 3
        _stmt.bindLong(_argIndex, neighborUid)
        _stmt.step()
        getTotalChangedRows(_connection)
      } finally {
        _stmt.close()
      }
    }
  }

  public override suspend fun updateStatuses(timeNow: Long, lostThreshold: Long) {
    val _sql: String = """
        |
        |        UPDATE NeighborCache
        |           SET neighborStatus = CAST(((? - NeighborCache.neighborLastSeen) < ?) AS INTEGER)
        |         WHERE neighborStatus != CAST(((? - NeighborCache.neighborLastSeen) < ?) AS INTEGER)   
        |    
        """.trimMargin()
    return performSuspending(__db, false, true) { _connection ->
      val _stmt: SQLiteStatement = _connection.prepare(_sql)
      try {
        var _argIndex: Int = 1
        _stmt.bindLong(_argIndex, timeNow)
        _argIndex = 2
        _stmt.bindLong(_argIndex, lostThreshold)
        _argIndex = 3
        _stmt.bindLong(_argIndex, timeNow)
        _argIndex = 4
        _stmt.bindLong(_argIndex, lostThreshold)
        _stmt.step()
      } finally {
        _stmt.close()
      }
    }
  }

  public override suspend fun updateDeviceName(neighborUid: Long, deviceName: String) {
    val _sql: String = """
        |
        |        UPDATE NeighborCache
        |           SET neighborDeviceName = ?
        |        WHERE neighborUid = ?
        |          AND neighborDeviceName != ?   
        |    
        """.trimMargin()
    return performSuspending(__db, false, true) { _connection ->
      val _stmt: SQLiteStatement = _connection.prepare(_sql)
      try {
        var _argIndex: Int = 1
        _stmt.bindText(_argIndex, deviceName)
        _argIndex = 2
        _stmt.bindLong(_argIndex, neighborUid)
        _argIndex = 3
        _stmt.bindText(_argIndex, deviceName)
        _stmt.step()
      } finally {
        _stmt.close()
      }
    }
  }

  public companion object {
    public fun getRequiredConverters(): List<KClass<*>> = emptyList()
  }
}
