/*
 * Copyright 2016-2017 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package kotlinx.coroutines.experimental

import kotlin.coroutines.experimental.Continuation
import kotlin.coroutines.experimental.intrinsics.COROUTINE_SUSPENDED

private const val UNDECIDED = 0
private const val SUSPENDED = 1
private const val RESUMED = 2

/**
 * @suppress **This is unstable API and it is subject to change.**
 */
internal abstract class AbstractContinuation<in T>(
    public final override val delegate: Continuation<T>,
    public final override val resumeMode: Int
) : JobSupport(true), Continuation<T>, DispatchedTask<T> {
    private var decision = UNDECIDED

    /* decision state machine

        +-----------+   trySuspend   +-----------+
        | UNDECIDED | -------------> | SUSPENDED |
        +-----------+                +-----------+
              |
              | tryResume
              V
        +-----------+
        |  RESUMED  |
        +-----------+

        Note: both tryResume and trySuspend can be invoked at most once, first invocation wins
     */

    override fun takeState(): Any? = state

    private fun trySuspend(): Boolean = when (decision) {
        UNDECIDED -> { decision = SUSPENDED; true }
        RESUMED -> false
        else -> error("Already suspended")
    }

    private fun tryResume(): Boolean = when (decision) {
        UNDECIDED -> { decision = RESUMED; true }
        SUSPENDED -> false
        else -> error("Already resumed")
    }

    @PublishedApi
    internal fun getResult(): Any? {
        if (trySuspend()) return COROUTINE_SUSPENDED
        // otherwise, afterCompletion was already invoked & invoked tryResume, and the result is in the state
        val state = this.state
        if (state is CompletedExceptionally) throw state.exception
        return getSuccessfulResult(state)
    }

    override fun afterCompletion(state: Any?, mode: Int) {
        if (tryResume()) return // completed before getResult invocation -- bail out
        // otherwise, getResult has already commenced, i.e. completed later or in other thread
        dispatch(mode)
    }

    override fun resume(value: T) =
        resumeImpl(value, resumeMode)

    override fun resumeWithException(exception: Throwable) =
        resumeImpl(CompletedExceptionally(exception), resumeMode)

    protected fun resumeImpl(proposedUpdate: Any?, resumeMode: Int) {
        val state = this.state
        return when (state) {
            is Incomplete -> updateState(proposedUpdate, resumeMode)
            is Cancelled -> {
                // Ignore resumes in cancelled coroutines, but handle exception if a different one here
                if (proposedUpdate is CompletedExceptionally && proposedUpdate.exception != state.exception)
                    handleException(proposedUpdate.exception)
                return
            }
            else -> error("Already resumed, but got $proposedUpdate")
        }
    }

    override fun handleException(exception: Throwable) {
        handleCoroutineException(context, exception)
    }
}