package de.kif.common

import de.kif.common.model.Model
import de.westermann.kobserve.event.EventHandler

abstract class CachedRepository<T : Model>(val repository: Repository<T>) : Repository<T> {

    override val onCreate = EventHandler<Long>()
    override val onUpdate = EventHandler<Long>()
    override val onDelete = EventHandler<Long>()

    private var cache: Map<Long, T> = emptyMap()
    private var cacheComplete: Boolean = false

    override suspend fun get(id: Long): T? {
        return if (id in cache) {
            cache[id]
        } else {
            val element = repository.get(id)

            if (element != null) {
                cache = cache + (id to element)
            }

            element
        }
    }

    override suspend fun create(model: T): Long {
        return repository.create(model)
    }

    override suspend fun update(model: T) {
        repository.update(model)
    }

    override suspend fun delete(id: Long) {
        repository.delete(id)
    }

    override suspend fun all(): List<T> {
        return if (cacheComplete) {
            cache.values.toList()
        } else {
            val all = repository.all()

            cache = all.associateBy { it.id!! }
            cacheComplete = true

            all
        }
    }

    init {
        repository.onCreate {
            cacheComplete = false
            cache = cache - it
        }
        repository.onUpdate {
            cacheComplete = false
            cache = cache - it
        }
        repository.onDelete {
            cache = cache - it
        }
    }
}
