package eu.smoser.epv

import android.content.Context
import androidx.room.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext

fun <R> CoroutineScope.executeAsyncTask(
    onPreExecute: () -> Unit,
    doInBackground: () -> R,
    onPostExecute: (R) -> Unit
) = launch {
    onPreExecute()
    val result = withContext(Dispatchers.IO) {
        doInBackground()
    }
    onPostExecute(result)
}

@Entity
data class User(
    @PrimaryKey val uid: Long,
    @ColumnInfo(name = "privilegien") val privilegien: Int,
)

@Dao
interface UserDao {
    @Query("SELECT * FROM user")
    fun getAll(): List<User>

    @Query("UPDATE user SET privilegien = privilegien + :modifier WHERE uid IN (:userIds)")
    fun updateAllPrivilegien(userIds: LongArray, modifier: Int)

    @Query("SELECT * FROM user WHERE uid == :id")
    fun findById(id: Long): User

    @Query("UPDATE user SET privilegien = :newPriv WHERE uid == :id")
    fun updatePrivilegien(id: Long, newPriv: Int)

    @Insert
    fun insert(user: User)

    @Delete
    fun delete(user: User)
}

@Database(entities = [User::class], version = 2)
abstract class AppDatabase : RoomDatabase() {
    abstract fun userDao(): UserDao?

    companion object {
        private const val DB_NAME = "UserDatabase.db"

        @Volatile
        private var appDatabase: AppDatabase? = null

        @Synchronized
        fun getInstance(context: Context): AppDatabase {
            if (appDatabase == null) appDatabase = create(context)
            return appDatabase!!
        }

        private fun create(context: Context): AppDatabase {
            return Room.databaseBuilder(
                context,
                AppDatabase::class.java,
                DB_NAME
            ).fallbackToDestructiveMigration().build()
        }
    }
}
