package com.ustadmobile.core.db.dao.xapi

import com.ustadmobile.door.DoorDbType
import com.ustadmobile.door.EntityInsertionAdapter
import com.ustadmobile.door.PreparedStatementConfig
import com.ustadmobile.door.ext.prepareAndUseStatementAsync
import com.ustadmobile.door.jdbc.PreparedStatement
import com.ustadmobile.door.jdbc.ext.executeQueryAsyncKmp
import com.ustadmobile.door.jdbc.ext.mapRows
import com.ustadmobile.door.jdbc.ext.useResults
import com.ustadmobile.door.room.RoomDatabase
import com.ustadmobile.lib.db.entities.xapi.StatementContextActivityJoin
import kotlin.Boolean
import kotlin.IllegalArgumentException
import kotlin.Int
import kotlin.Long
import kotlin.String
import kotlin.collections.List

public class StatementContextActivityJoinDao_JdbcImpl(
  public val _db: RoomDatabase,
) : StatementContextActivityJoinDao() {
  public val _insertAdapterStatementContextActivityJoin_ignore:
      EntityInsertionAdapter<StatementContextActivityJoin> = object :
      EntityInsertionAdapter<StatementContextActivityJoin>(_db) {
    override fun makeSql(returnsId: Boolean): String = when(dbType) {
      DoorDbType.SQLITE -> {
        "INSERT  OR IGNORE INTO StatementContextActivityJoin (scajFromStatementIdHi, scajFromStatementIdLo, scajToHash, scajContextType, scajToActivityUid, scajToActivityId, scajEtag) VALUES(?, ?, ?, ?, ?, ?, ?)"
      }
      DoorDbType.POSTGRES ->  {
        "INSERT INTO StatementContextActivityJoin (scajFromStatementIdHi, scajFromStatementIdLo, scajToHash, scajContextType, scajToActivityUid, scajToActivityId, scajEtag) VALUES(?, ?, ?, ?, ?, ?, ?) ON CONFLICT (scajFromStatementIdHi, scajFromStatementIdLo, scajToHash) DO NOTHING" + if(returnsId) { " RETURNING scajFromStatementIdHi" } else "" 
      }
      else -> {
        throw IllegalArgumentException("Unsupported db type")
      }
    }

    override fun bindPreparedStmtToEntity(stmt: PreparedStatement,
        entity: StatementContextActivityJoin) {
      stmt.setLong(1, entity.scajFromStatementIdHi)
      stmt.setLong(2, entity.scajFromStatementIdLo)
      stmt.setLong(3, entity.scajToHash)
      stmt.setInt(4, entity.scajContextType)
      stmt.setLong(5, entity.scajToActivityUid)
      stmt.setString(6, entity.scajToActivityId)
      stmt.setLong(7, entity.scajEtag)
    }
  }

  override suspend fun insertOrIgnoreListAsync(entities: List<StatementContextActivityJoin>) {
    _insertAdapterStatementContextActivityJoin_ignore.insertListAsync(entities)
  }

  override suspend fun findAllByStatementId(
    statementIdHi: Long,
    statementIdLo: Long,
    scajContextType: Int,
  ): List<StatementContextActivityJoin> = _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = """
    |
    |        SELECT StatementContextActivityJoin.*
    |          FROM StatementContextActivityJoin
    |         WHERE StatementContextActivityJoin.scajFromStatementIdHi = ?
    |           AND StatementContextActivityJoin.scajFromStatementIdLo = ?
    |           AND StatementContextActivityJoin.scajContextType = ?
    |    
    """.trimMargin(),
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,statementIdHi)
    _stmt.setLong(2,statementIdLo)
    _stmt.setInt(3,scajContextType)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapRows {
        val _tmp_scajFromStatementIdHi = _result.getLong("scajFromStatementIdHi")
        val _tmp_scajFromStatementIdLo = _result.getLong("scajFromStatementIdLo")
        val _tmp_scajToHash = _result.getLong("scajToHash")
        val _tmp_scajContextType = _result.getInt("scajContextType")
        val _tmp_scajToActivityUid = _result.getLong("scajToActivityUid")
        val _tmp_scajToActivityId = _result.getString("scajToActivityId")
        val _tmp_scajEtag = _result.getLong("scajEtag")
        StatementContextActivityJoin().apply {
          this.scajFromStatementIdHi = _tmp_scajFromStatementIdHi
          this.scajFromStatementIdLo = _tmp_scajFromStatementIdLo
          this.scajToHash = _tmp_scajToHash
          this.scajContextType = _tmp_scajContextType
          this.scajToActivityUid = _tmp_scajToActivityUid
          this.scajToActivityId = _tmp_scajToActivityId
          this.scajEtag = _tmp_scajEtag
        }
      }
    }
  }
}
