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.VerbLangMapEntry
import kotlin.Boolean
import kotlin.IllegalArgumentException
import kotlin.Long
import kotlin.String
import kotlin.collections.List

public class VerbLangMapEntryDao_JdbcImpl(
  public val _db: RoomDatabase,
) : VerbLangMapEntryDao() {
  public val _insertAdapterVerbLangMapEntry_upsert: EntityInsertionAdapter<VerbLangMapEntry> =
      object : EntityInsertionAdapter<VerbLangMapEntry>(_db) {
    override fun makeSql(returnsId: Boolean): String = when(dbType) {
      DoorDbType.SQLITE -> {
        "INSERT OR REPLACE INTO VerbLangMapEntry (vlmeVerbUid, vlmeLangHash, vlmeLangCode, vlmeEntryString, vlmeLastModified) VALUES(?, ?, ?, ?, ?)"
      }
      DoorDbType.POSTGRES ->  {
        "INSERT INTO VerbLangMapEntry (vlmeVerbUid, vlmeLangHash, vlmeLangCode, vlmeEntryString, vlmeLastModified) VALUES(?, ?, ?, ?, ?) ON CONFLICT (vlmeVerbUid, vlmeLangHash) DO UPDATE SET vlmeLangCode = excluded.vlmeLangCode,vlmeEntryString = excluded.vlmeEntryString,vlmeLastModified = excluded.vlmeLastModified" + if(returnsId) { " RETURNING vlmeVerbUid" } else "" 
      }
      else -> {
        throw IllegalArgumentException("Unsupported db type")
      }
    }

    override fun bindPreparedStmtToEntity(stmt: PreparedStatement, entity: VerbLangMapEntry) {
      stmt.setLong(1, entity.vlmeVerbUid)
      stmt.setLong(2, entity.vlmeLangHash)
      stmt.setString(3, entity.vlmeLangCode)
      stmt.setString(4, entity.vlmeEntryString)
      stmt.setLong(5, entity.vlmeLastModified)
    }
  }

  override suspend fun upsertList(list: List<VerbLangMapEntry>) {
    _insertAdapterVerbLangMapEntry_upsert.insertListAsync(list)
  }

  override suspend fun findByVerbUidAsync(verbUid: Long): List<VerbLangMapEntry> =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = """
    |
    |        SELECT VerbLangMapEntry.*
    |          FROM VerbLangMapEntry
    |         WHERE VerbLangMapEntry.vlmeVerbUid = ?
    |    
    """.trimMargin(),
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,verbUid)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapRows {
        val _tmp_vlmeVerbUid = _result.getLong("vlmeVerbUid")
        val _tmp_vlmeLangHash = _result.getLong("vlmeLangHash")
        val _tmp_vlmeLangCode = _result.getString("vlmeLangCode")
        val _tmp_vlmeEntryString = _result.getString("vlmeEntryString")
        val _tmp_vlmeLastModified = _result.getLong("vlmeLastModified")
        VerbLangMapEntry().apply {
          this.vlmeVerbUid = _tmp_vlmeVerbUid
          this.vlmeLangHash = _tmp_vlmeLangHash
          this.vlmeLangCode = _tmp_vlmeLangCode
          this.vlmeEntryString = _tmp_vlmeEntryString
          this.vlmeLastModified = _tmp_vlmeLastModified
        }
      }
    }
  }
}
