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

public class ActivityExtensionDao_JdbcImpl(
  public val _db: RoomDatabase,
) : ActivityExtensionDao() {
  public val _insertAdapterActivityExtensionEntity_upsert:
      EntityInsertionAdapter<ActivityExtensionEntity> = object :
      EntityInsertionAdapter<ActivityExtensionEntity>(_db) {
    override fun makeSql(returnsId: Boolean): String = when(dbType) {
      DoorDbType.SQLITE -> {
        "INSERT OR REPLACE INTO ActivityExtensionEntity (aeeActivityUid, aeeKeyHash, aeeKey, aeeJson, aeeLastMod, aeeIsDeleted) VALUES(?, ?, ?, ?, ?, ?)"
      }
      DoorDbType.POSTGRES ->  {
        "INSERT INTO ActivityExtensionEntity (aeeActivityUid, aeeKeyHash, aeeKey, aeeJson, aeeLastMod, aeeIsDeleted) VALUES(?, ?, ?, ?, ?, ?) ON CONFLICT (aeeActivityUid, aeeKeyHash) DO UPDATE SET aeeKey = excluded.aeeKey,aeeJson = excluded.aeeJson,aeeLastMod = excluded.aeeLastMod,aeeIsDeleted = excluded.aeeIsDeleted" + if(returnsId) { " RETURNING aeeActivityUid" } else "" 
      }
      else -> {
        throw IllegalArgumentException("Unsupported db type")
      }
    }

    override fun bindPreparedStmtToEntity(stmt: PreparedStatement,
        entity: ActivityExtensionEntity) {
      stmt.setLong(1, entity.aeeActivityUid)
      stmt.setLong(2, entity.aeeKeyHash)
      stmt.setString(3, entity.aeeKey)
      stmt.setString(4, entity.aeeJson)
      stmt.setLong(5, entity.aeeLastMod)
      stmt.setBoolean(6, entity.aeeIsDeleted)
    }
  }

  override suspend fun upsertListAsync(list: List<ActivityExtensionEntity>) {
    _insertAdapterActivityExtensionEntity_upsert.insertListAsync(list)
  }

  override suspend fun findAllByActivityUid(activityUid: Long): List<ActivityExtensionEntity> =
      _db.prepareAndUseStatementAsync(PreparedStatementConfig(
    sql = """
    |
    |        SELECT ActivityExtensionEntity.*
    |          FROM ActivityExtensionEntity
    |         WHERE ActivityExtensionEntity.aeeActivityUid = ? 
    |    
    """.trimMargin(),
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setLong(1,activityUid)
    _stmt.executeQueryAsyncKmp().useResults{ _result -> 
      _result.mapRows {
        val _tmp_aeeActivityUid = _result.getLong("aeeActivityUid")
        val _tmp_aeeKeyHash = _result.getLong("aeeKeyHash")
        val _tmp_aeeKey = _result.getString("aeeKey")
        val _tmp_aeeJson = _result.getString("aeeJson")
        val _tmp_aeeLastMod = _result.getLong("aeeLastMod")
        val _tmp_aeeIsDeleted = _result.getBoolean("aeeIsDeleted")
        ActivityExtensionEntity().apply {
          this.aeeActivityUid = _tmp_aeeActivityUid
          this.aeeKeyHash = _tmp_aeeKeyHash
          this.aeeKey = _tmp_aeeKey
          this.aeeJson = _tmp_aeeJson
          this.aeeLastMod = _tmp_aeeLastMod
          this.aeeIsDeleted = _tmp_aeeIsDeleted
        }
      }
    }
  }
}
