package com.ustadmobile.core.db.dao

import com.ustadmobile.door.DoorConstants
import com.ustadmobile.door.ext.doorWrapperNodeId
import com.ustadmobile.door.http.DoorHttpServerConfig
import com.ustadmobile.door.http.DoorJsonRequest
import com.ustadmobile.door.http.DoorJsonResponse
import com.ustadmobile.door.message.DoorMessage
import com.ustadmobile.door.replication.DoorReplicationEntity
import com.ustadmobile.lib.db.entities.ClazzEnrolment
import com.ustadmobile.lib.db.entities.CourseGroupMember
import com.ustadmobile.lib.db.entities.Person
import com.ustadmobile.lib.db.entities.PersonPicture
import kotlin.Int
import kotlin.Long
import kotlin.Suppress
import kotlin.collections.buildList
import kotlinx.coroutines.flow.first
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.json.jsonObject

@Suppress("LocalVariableName", "RedundantSuppression", "FunctionName",
    "RedundantVisibilityModifier")
public suspend
    fun CourseGroupMemberDao.findByCourseGroupSetAndClazz_DoorHttp(serverConfig: DoorHttpServerConfig,
    request: DoorJsonRequest): DoorJsonResponse {
  val json = serverConfig.json
  val _arg_cgsUid : Long = request.queryParam("cgsUid")?.let {
    json.decodeFromString(Long.serializer(), it)
  } ?: 0L
  val _arg_clazzUid : Long = request.queryParam("clazzUid")?.let {
    json.decodeFromString(Long.serializer(), it)
  } ?: 0L
  val _arg_time : Long = request.queryParam("time")?.let {
    json.decodeFromString(Long.serializer(), it)
  } ?: 0L
  val _arg_activeFilter : Int = request.queryParam("activeFilter")?.let {
    json.decodeFromString(Int.serializer(), it)
  } ?: 0
  val _arg_accountPersonUid : Long = request.queryParam("accountPersonUid")?.let {
    json.decodeFromString(Long.serializer(), it)
  } ?: 0L
  val _result_findByCourseGroupSetAndClazz = findByCourseGroupSetAndClazz(
    cgsUid = _arg_cgsUid,
    clazzUid = _arg_clazzUid,
    time = _arg_time,
    activeFilter = _arg_activeFilter,
    accountPersonUid = _arg_accountPersonUid,
  )
  val _result_findByCourseGroupSetAndClazzAsFlowPersons = findByCourseGroupSetAndClazzAsFlowPersons(
    clazzUid = _arg_clazzUid,
    cgsUid = _arg_cgsUid,
  )
  val _result_findByCourseGroupSetAndClazzAsFlowEnrolments =
      findByCourseGroupSetAndClazzAsFlowEnrolments(
    clazzUid = _arg_clazzUid,
    cgsUid = _arg_cgsUid,
  )
  val replicationEntities = buildList<DoorReplicationEntity> {
    addAll(
      _result_findByCourseGroupSetAndClazz.mapNotNull {
        _row ->
        _row.cgm?.let {
          DoorReplicationEntity(tableId = 243,
            orUid = 0,
            entity = json.encodeToJsonElement(CourseGroupMember.serializer(), it).jsonObject,
          )
        }

      }
    )
    addAll(
      _result_findByCourseGroupSetAndClazzAsFlowPersons.mapNotNull {
        _row ->
        _row.person?.let {
          DoorReplicationEntity(tableId = 9,
            orUid = 0,
            entity = json.encodeToJsonElement(Person.serializer(), it).jsonObject,
          )
        }

      }
    )
    addAll(
      _result_findByCourseGroupSetAndClazzAsFlowPersons.mapNotNull {
        _row ->
        _row.picture?.let {
          DoorReplicationEntity(tableId = 50,
            orUid = 0,
            entity = json.encodeToJsonElement(PersonPicture.serializer(), it).jsonObject,
          )
        }

      }
    )
    addAll(
      _result_findByCourseGroupSetAndClazzAsFlowEnrolments.map {
        _row ->
        DoorReplicationEntity(tableId = 65,
          orUid = 0,
          entity = json.encodeToJsonElement(ClazzEnrolment.serializer(), _row).jsonObject,
        )
      }
    )
  }
  val _thisNodeId = request.db.doorWrapperNodeId
  return DoorJsonResponse(
    headers = buildList {
      add(Pair(DoorConstants.HEADER_NODE_ID, _thisNodeId.toString()))
    }
    ,
    bodyText = json.encodeToString(
      DoorMessage.serializer(),
      DoorMessage(
        what = DoorMessage.WHAT_REPLICATION_PULL,
        fromNode = _thisNodeId,
        toNode = request.requireNodeId(),
        replications = replicationEntities,
      )
    )
  )
}

@Suppress("LocalVariableName", "RedundantSuppression", "FunctionName",
    "RedundantVisibilityModifier")
public suspend
    fun CourseGroupMemberDao.findByCourseGroupSetAndClazzAsFlow_DoorHttp(serverConfig: DoorHttpServerConfig,
    request: DoorJsonRequest): DoorJsonResponse {
  val json = serverConfig.json
  val _arg_cgsUid : Long = request.queryParam("cgsUid")?.let {
    json.decodeFromString(Long.serializer(), it)
  } ?: 0L
  val _arg_clazzUid : Long = request.queryParam("clazzUid")?.let {
    json.decodeFromString(Long.serializer(), it)
  } ?: 0L
  val _arg_time : Long = request.queryParam("time")?.let {
    json.decodeFromString(Long.serializer(), it)
  } ?: 0L
  val _arg_activeFilter : Int = request.queryParam("activeFilter")?.let {
    json.decodeFromString(Int.serializer(), it)
  } ?: 0
  val _arg_accountPersonUid : Long = request.queryParam("accountPersonUid")?.let {
    json.decodeFromString(Long.serializer(), it)
  } ?: 0L
  val _result_findByCourseGroupSetAndClazzAsFlow = findByCourseGroupSetAndClazzAsFlow(
    cgsUid = _arg_cgsUid,
    clazzUid = _arg_clazzUid,
    time = _arg_time,
    activeFilter = _arg_activeFilter,
    accountPersonUid = _arg_accountPersonUid,
  ).first()
  val _result_findByCourseGroupSetAndClazzAsFlowPersons = findByCourseGroupSetAndClazzAsFlowPersons(
    clazzUid = _arg_clazzUid,
    cgsUid = _arg_cgsUid,
  )
  val _result_findByCourseGroupSetAndClazzAsFlowEnrolments =
      findByCourseGroupSetAndClazzAsFlowEnrolments(
    clazzUid = _arg_clazzUid,
    cgsUid = _arg_cgsUid,
  )
  val replicationEntities = buildList<DoorReplicationEntity> {
    addAll(
      _result_findByCourseGroupSetAndClazzAsFlow.mapNotNull {
        _row ->
        _row.cgm?.let {
          DoorReplicationEntity(tableId = 243,
            orUid = 0,
            entity = json.encodeToJsonElement(CourseGroupMember.serializer(), it).jsonObject,
          )
        }

      }
    )
    addAll(
      _result_findByCourseGroupSetAndClazzAsFlowPersons.mapNotNull {
        _row ->
        _row.person?.let {
          DoorReplicationEntity(tableId = 9,
            orUid = 0,
            entity = json.encodeToJsonElement(Person.serializer(), it).jsonObject,
          )
        }

      }
    )
    addAll(
      _result_findByCourseGroupSetAndClazzAsFlowPersons.mapNotNull {
        _row ->
        _row.picture?.let {
          DoorReplicationEntity(tableId = 50,
            orUid = 0,
            entity = json.encodeToJsonElement(PersonPicture.serializer(), it).jsonObject,
          )
        }

      }
    )
    addAll(
      _result_findByCourseGroupSetAndClazzAsFlowEnrolments.map {
        _row ->
        DoorReplicationEntity(tableId = 65,
          orUid = 0,
          entity = json.encodeToJsonElement(ClazzEnrolment.serializer(), _row).jsonObject,
        )
      }
    )
  }
  val _thisNodeId = request.db.doorWrapperNodeId
  return DoorJsonResponse(
    headers = buildList {
      add(Pair(DoorConstants.HEADER_NODE_ID, _thisNodeId.toString()))
    }
    ,
    bodyText = json.encodeToString(
      DoorMessage.serializer(),
      DoorMessage(
        what = DoorMessage.WHAT_REPLICATION_PULL,
        fromNode = _thisNodeId,
        toNode = request.requireNodeId(),
        replications = replicationEntities,
      )
    )
  )
}

@Suppress("LocalVariableName", "RedundantSuppression", "FunctionName",
    "RedundantVisibilityModifier")
public suspend
    fun CourseGroupMemberDao.findByCourseGroupSetAndGroupNumAsync_DoorHttp(serverConfig: DoorHttpServerConfig,
    request: DoorJsonRequest): DoorJsonResponse {
  val json = serverConfig.json
  val _arg_courseGroupSetUid : Long = request.queryParam("courseGroupSetUid")?.let {
    json.decodeFromString(Long.serializer(), it)
  } ?: 0L
  val _arg_groupNum : Int = request.queryParam("groupNum")?.let {
    json.decodeFromString(Int.serializer(), it)
  } ?: 0
  val _arg_clazzUid : Long = request.queryParam("clazzUid")?.let {
    json.decodeFromString(Long.serializer(), it)
  } ?: 0L
  val _arg_assignmentUid : Long = request.queryParam("assignmentUid")?.let {
    json.decodeFromString(Long.serializer(), it)
  } ?: 0L
  val _arg_accountPersonUid : Long = request.queryParam("accountPersonUid")?.let {
    json.decodeFromString(Long.serializer(), it)
  } ?: 0L
  val _result_findByCourseGroupSetAndGroupNumAsync = findByCourseGroupSetAndGroupNumAsync(
    courseGroupSetUid = _arg_courseGroupSetUid,
    groupNum = _arg_groupNum,
    clazzUid = _arg_clazzUid,
    assignmentUid = _arg_assignmentUid,
    accountPersonUid = _arg_accountPersonUid,
  )
  val replicationEntities = buildList<DoorReplicationEntity> {
    addAll(
      _result_findByCourseGroupSetAndGroupNumAsync.mapNotNull {
        _row ->
        _row.courseGroupMember?.let {
          DoorReplicationEntity(tableId = 243,
            orUid = 0,
            entity = json.encodeToJsonElement(CourseGroupMember.serializer(), it).jsonObject,
          )
        }

      }
    )
    addAll(
      _result_findByCourseGroupSetAndGroupNumAsync.mapNotNull {
        _row ->
        _row.person?.let {
          DoorReplicationEntity(tableId = 9,
            orUid = 0,
            entity = json.encodeToJsonElement(Person.serializer(), it).jsonObject,
          )
        }

      }
    )
  }
  val _thisNodeId = request.db.doorWrapperNodeId
  return DoorJsonResponse(
    headers = buildList {
      add(Pair(DoorConstants.HEADER_NODE_ID, _thisNodeId.toString()))
    }
    ,
    bodyText = json.encodeToString(
      DoorMessage.serializer(),
      DoorMessage(
        what = DoorMessage.WHAT_REPLICATION_PULL,
        fromNode = _thisNodeId,
        toNode = request.requireNodeId(),
        replications = replicationEntities,
      )
    )
  )
}
