package com.ustadmobile.core.db.dao

import com.ustadmobile.door.DoorDbType
import com.ustadmobile.door.EntityInsertionAdapter
import com.ustadmobile.door.PreparedStatementConfig
import com.ustadmobile.door.ext.prepareAndUseStatement
import com.ustadmobile.door.jdbc.PreparedStatement
import com.ustadmobile.door.jdbc.ext.mapNextRow
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.ContentCategorySchema
import kotlin.Boolean
import kotlin.IllegalArgumentException
import kotlin.Long
import kotlin.String
import kotlin.collections.List

public class ContentCategorySchemaDao_JdbcImpl(
  public val _db: RoomDatabase,
) : ContentCategorySchemaDao() {
  public val _insertAdapterContentCategorySchema_abort:
      EntityInsertionAdapter<ContentCategorySchema> = object :
      EntityInsertionAdapter<ContentCategorySchema>(_db) {
    override fun makeSql(returnsId: Boolean): String = when(dbType) {
      DoorDbType.SQLITE -> {
        "INSERT INTO ContentCategorySchema (contentCategorySchemaUid, schemaName, schemaUrl, contentCategorySchemaLocalChangeSeqNum, contentCategorySchemaMasterChangeSeqNum, contentCategorySchemaLastChangedBy, contentCategorySchemaLct) VALUES(?, ?, ?, ?, ?, ?, ?)"
      }
      DoorDbType.POSTGRES ->  {
        "INSERT INTO ContentCategorySchema (contentCategorySchemaUid, schemaName, schemaUrl, contentCategorySchemaLocalChangeSeqNum, contentCategorySchemaMasterChangeSeqNum, contentCategorySchemaLastChangedBy, contentCategorySchemaLct) VALUES(COALESCE(?,nextval('ContentCategorySchema_contentCategorySchemaUid_seq')), ?, ?, ?, ?, ?, ?)" + if(returnsId) { " RETURNING contentCategorySchemaUid" } else "" 
      }
      else -> {
        throw IllegalArgumentException("Unsupported db type")
      }
    }

    override fun bindPreparedStmtToEntity(stmt: PreparedStatement, entity: ContentCategorySchema) {
      if(entity.contentCategorySchemaUid == 0L) {
        stmt.setObject(1, null)
      } else {
        stmt.setLong(1, entity.contentCategorySchemaUid)
      }
      stmt.setString(2, entity.schemaName)
      stmt.setString(3, entity.schemaUrl)
      stmt.setLong(4, entity.contentCategorySchemaLocalChangeSeqNum)
      stmt.setLong(5, entity.contentCategorySchemaMasterChangeSeqNum)
      stmt.setInt(6, entity.contentCategorySchemaLastChangedBy)
      stmt.setLong(7, entity.contentCategorySchemaLct)
    }
  }

  public override fun insert(entity: ContentCategorySchema): Long {
    val _retVal = _insertAdapterContentCategorySchema_abort.insertAndReturnId(entity)
    return _retVal
  }

  public override suspend fun insertAsync(entity: ContentCategorySchema): Long {
    val _retVal = _insertAdapterContentCategorySchema_abort.insertAndReturnIdAsync(entity)
    return _retVal
  }

  public override fun insertList(entityList: List<ContentCategorySchema>) {
    _insertAdapterContentCategorySchema_abort.insertList(entityList)
  }

  public override fun update(entity: ContentCategorySchema) {
    val _sql =
        "UPDATE ContentCategorySchema SET schemaName = ?, schemaUrl = ?, contentCategorySchemaLocalChangeSeqNum = ?, contentCategorySchemaMasterChangeSeqNum = ?, contentCategorySchemaLastChangedBy = ?, contentCategorySchemaLct = ? WHERE contentCategorySchemaUid = ?"
    _db.prepareAndUseStatement(_sql) {
       _stmt ->
      _stmt.setString(1, entity.schemaName)
      _stmt.setString(2, entity.schemaUrl)
      _stmt.setLong(3, entity.contentCategorySchemaLocalChangeSeqNum)
      _stmt.setLong(4, entity.contentCategorySchemaMasterChangeSeqNum)
      _stmt.setInt(5, entity.contentCategorySchemaLastChangedBy)
      _stmt.setLong(6, entity.contentCategorySchemaLct)
      _stmt.setLong(7, entity.contentCategorySchemaUid)
      _stmt.executeUpdate()
    }
  }

  override fun publicContentCategorySchemas(): List<ContentCategorySchema> =
      _db.prepareAndUseStatement(PreparedStatementConfig(
    sql = "SELECT ContentCategorySchema.* FROM ContentCategorySchema",
    readOnly = true,)
  ) { _stmt -> 
    _stmt.executeQuery().useResults{ _result -> 
      _result.mapRows {
        val _tmp_contentCategorySchemaUid = _result.getLong("contentCategorySchemaUid")
        val _tmp_schemaName = _result.getString("schemaName")
        val _tmp_schemaUrl = _result.getString("schemaUrl")
        val _tmp_contentCategorySchemaLocalChangeSeqNum =
            _result.getLong("contentCategorySchemaLocalChangeSeqNum")
        val _tmp_contentCategorySchemaMasterChangeSeqNum =
            _result.getLong("contentCategorySchemaMasterChangeSeqNum")
        val _tmp_contentCategorySchemaLastChangedBy =
            _result.getInt("contentCategorySchemaLastChangedBy")
        val _tmp_contentCategorySchemaLct = _result.getLong("contentCategorySchemaLct")
        ContentCategorySchema().apply {
          this.contentCategorySchemaUid = _tmp_contentCategorySchemaUid
          this.schemaName = _tmp_schemaName
          this.schemaUrl = _tmp_schemaUrl
          this.contentCategorySchemaLocalChangeSeqNum = _tmp_contentCategorySchemaLocalChangeSeqNum
          this.contentCategorySchemaMasterChangeSeqNum =
              _tmp_contentCategorySchemaMasterChangeSeqNum
          this.contentCategorySchemaLastChangedBy = _tmp_contentCategorySchemaLastChangedBy
          this.contentCategorySchemaLct = _tmp_contentCategorySchemaLct
        }
      }
    }
  }

  override fun findBySchemaUrl(schemaUrl: String): ContentCategorySchema? =
      _db.prepareAndUseStatement(PreparedStatementConfig(
    sql = "SELECT * FROM ContentCategorySchema WHERE schemaUrl = ?",
    readOnly = true,)
  ) { _stmt -> 
    _stmt.setString(1,schemaUrl)
    _stmt.executeQuery().useResults{ _result -> 
      _result.mapNextRow(null) {
        val _tmp_contentCategorySchemaUid = _result.getLong("contentCategorySchemaUid")
        val _tmp_schemaName = _result.getString("schemaName")
        val _tmp_schemaUrl = _result.getString("schemaUrl")
        val _tmp_contentCategorySchemaLocalChangeSeqNum =
            _result.getLong("contentCategorySchemaLocalChangeSeqNum")
        val _tmp_contentCategorySchemaMasterChangeSeqNum =
            _result.getLong("contentCategorySchemaMasterChangeSeqNum")
        val _tmp_contentCategorySchemaLastChangedBy =
            _result.getInt("contentCategorySchemaLastChangedBy")
        val _tmp_contentCategorySchemaLct = _result.getLong("contentCategorySchemaLct")
        ContentCategorySchema().apply {
          this.contentCategorySchemaUid = _tmp_contentCategorySchemaUid
          this.schemaName = _tmp_schemaName
          this.schemaUrl = _tmp_schemaUrl
          this.contentCategorySchemaLocalChangeSeqNum = _tmp_contentCategorySchemaLocalChangeSeqNum
          this.contentCategorySchemaMasterChangeSeqNum =
              _tmp_contentCategorySchemaMasterChangeSeqNum
          this.contentCategorySchemaLastChangedBy = _tmp_contentCategorySchemaLastChangedBy
          this.contentCategorySchemaLct = _tmp_contentCategorySchemaLct
        }
      }
    }
  }
}
