package inn.ocsf.bee.freigeld.core.repo

import inn.ocsf.bee.freigeld.core.model.PublicLink
import inn.ocsf.bee.freigeld.utils.ZBase32Utils
import org.apache.commons.lang3.RandomStringUtils
import org.springframework.context.annotation.Lazy
import org.springframework.transaction.annotation.Transactional
import java.util.function.Function
import javax.inject.Inject

open class PublicLinkRepositoryImpl : PublicLinkRepositoryCustom {

    @Inject
    @Lazy
    private lateinit var linkRepo: PublicLinkRepository

    private fun getIds(): Set<String> {
        return (2..5).flatMap { l ->
            (1..5).map { n ->
                val str = RandomStringUtils.randomAlphanumeric(l)
                ZBase32Utils.encode(str).trim('=')
            }
        }.toSet()
    }

    @Transactional
    override fun getFreeIdAndSave(fn: Function<String, PublicLink?>): PublicLink? {
        var ret: PublicLink? = null
        while (ret == null) {
            val id = getIds().filter { !linkRepo.existsById(it) }.firstOrNull()
            if (id != null) {
                val ret0 = fn.apply(id)
                if (ret0 == null) throw RuntimeException("should not be null")
                if (ret0.id != id) throw RuntimeException("wrong id")
                ret = linkRepo.save(ret0)
            }
        }
        return ret
    }
}