/*
 * Copyright 2016-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license.
 */

package kotlinx.coroutines.experimental.io.internal

import java.nio.*
import java.util.concurrent.atomic.*
import kotlin.reflect.*

internal fun ByteBuffer.isEmpty() = !hasRemaining()

internal inline fun <reified Owner : Any> longUpdater(p: KProperty1<Owner, Long>): AtomicLongFieldUpdater<Owner> {
    return AtomicLongFieldUpdater.newUpdater(Owner::class.java, p.name)
}

internal inline fun <reified Owner : Any> intUpdater(p: KProperty1<Owner, Int>): AtomicIntegerFieldUpdater<Owner> {
    return AtomicIntegerFieldUpdater.newUpdater(Owner::class.java, p.name)
}

internal inline fun <reified Owner : Any, reified T> updater(p: KProperty1<Owner, T>): AtomicReferenceFieldUpdater<Owner, T> {
    return AtomicReferenceFieldUpdater.newUpdater(Owner::class.java, T::class.java, p.name)
}

internal fun getIOIntProperty(name: String, default: Int): Int =
    try { System.getProperty("kotlinx.coroutines.io.$name") }
    catch (e: SecurityException) { null }
        ?.toIntOrNull() ?: default


@Suppress("LoopToCallChain")
internal fun ByteBuffer.indexOfPartial(sub: ByteBuffer): Int {
    val subPosition = sub.position()
    val subSize = sub.remaining()
    val first = sub[subPosition]
    val limit = limit()

    outer@for (idx in position() until limit) {
        if (get(idx) == first) {
            for (j in 1 until subSize) {
                if (idx + j == limit) break
                if (get(idx + j) != sub.get(subPosition + j)) continue@outer
            }
            return idx - position()
        }
    }

    return -1
}

@Suppress("LoopToCallChain")
internal fun ByteBuffer.startsWith(prefix: ByteBuffer, prefixSkip: Int = 0): Boolean {
    val size = minOf(remaining(), prefix.remaining() - prefixSkip)
    if (size <= 0) return false

    val position = position()
    val prefixPosition = prefix.position() + prefixSkip

    for (i in 0 until size) {
        if (get(position + i) != prefix.get(prefixPosition + i)) return false
    }

    return true
}

internal fun ByteBuffer.putAtMost(src: ByteBuffer, n: Int = src.remaining()): Int {
    val rem = remaining()
    val srcRem = src.remaining()

    return when {
        srcRem <= rem && srcRem <= n -> {
            put(src)
            srcRem
        }
        else -> {
            val size = minOf(rem, srcRem, n)
            for (idx in 1..size) {
                put(src.get())
            }
            size
        }
    }
}

internal fun ByteBuffer.putLimited(src: ByteBuffer, limit: Int = limit()): Int {
    return putAtMost(src, limit - src.position())
}

internal fun ByteArray.asByteBuffer(offset: Int = 0, length: Int = size): ByteBuffer = ByteBuffer.wrap(this, offset, length)