/*
 * Copyright 2015 Nest Labs, Inc.
 *
 * 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.
 */

#pragma once

#include <cassert>
#include <mutex>
#include <condition_variable>
#include <memory>

#ifdef __GNUC__
#define FOLLY_CANCELLATION_WARN_UNUSED __attribute__((warn_unused_result))
#else
#define FOLLY_CANCELLATION_WARN_UNUSED
#endif

#include <folly/detail/CancellationDetail.h>

namespace folly {

/**
 * RAII object to prevent a Cancellation state from changing
 *
 * CancellationStateLock shall not be re-lockable. This is because
 * after you've unlocked it, it is possible that the underlying
 * cancellation was cancelled. There isn't a reliable way to represent
 * this other than throwing an exception.
 *
 * This object is convertable to bool. If it becomes `true', then
 * Cancellation IS NOT cancelled and you may proceed as normal. If it
 * becomes `false' then the Cancellation has been CANCELLED.
 *
 * <code>
 *     auto lock = Cancellation.hold_state();
 *     if (lock) {                         // i.e. static_cast<bool>(lock)
 *         // NOT cancelled
 *     } else {
 *         // CANCELLED
 *     }
 * </code>
 *
 * This is implemented using the "try_lock()" idiom of
 * std::unique_lock<T>.  Thus operator bool() is implemented to return
 * 'true' if the lock is acquired, and 'false' if not. In the case of
 * a Cancellation object, returning `true' means that we've acquired a
 * hold on the "un-cancelled" state. `false' means that the
 * Cancellation has been cancelled.
 */
class CancellationStateLock : public std::unique_lock<detail::CancellationSharedState>
{
public:
    friend class Cancellation;

    using base_type = std::unique_lock<detail::CancellationSharedState>;

    /* Should only be constructed in Cancellation::hold_state() */
    CancellationStateLock() = delete;

    ~CancellationStateLock() = default;

    /* non-copyable */
    CancellationStateLock(const CancellationStateLock& o) = delete;
    CancellationStateLock& operator= (const CancellationStateLock& o) = delete;

    /**
     * move constructor
     */
    CancellationStateLock(CancellationStateLock&& o) :
        base_type(std::forward<base_type>(o))
    {}

    /**
     * move operator
     */
    CancellationStateLock& operator= (CancellationStateLock&& o)
    {
        base_type::operator=(std::forward<base_type>(o));
        return *this;
    }

private:
    /**
     * Construct a lock that refers to a specific CancellationSharedState
     *
     */
    CancellationStateLock(detail::CancellationSharedState& ss, std::try_to_lock_t tag)
        : base_type(ss, tag)
    {
    }

    /**
     * This is made private to prevent its use (i.e. for re-lock()).
     */
    void lock();
};

/**
 * A thread-safe Cancellation object
 *
 * This is a token that is used to indicate whether or not some
 * operation or object is cancelled, deleted, out of date,
 * whatever. Like a mutex, this is an advisory token, and therefore it
 * is up to the programmer to use it properly.
 *
 * It is implemented so that all objects refer to a shared state (much
 * like a shared_ptr). Thus, all copies of the object refer to the
 * same shared state object. Therefore a Cancellation token can be
 * freely copied (by value), retaining a reference to the same shared
 * state as the copied-from token.
 *
 * It has a very simple state machine:
 *
 * <code>
 *                               cancel()
 * start --> [NOT CANCELLED] ----------------> [CANCELLED]
 * </code>
 *
 * The CANCELLED state is terminal.
 */
class Cancellation
{
public:
    /**
     * Construct a new cancellation object.
     */
    Cancellation() :
        _d(new detail::CancellationSharedState)
    {}

    /**
     * Copy constructor
     *
     * The new Cancellation will refer to the same shared state as `o'.
     *
     * @param o an existing Cancellation object from whom we get our
     * shared state.
     */
    Cancellation(const Cancellation& o) :
        _d(o._d)
    {}

    /**
     * Assignment operator
     *
     * On return, the Cancellation will refer to the same shared state as `o'.
     * We will drop the reference to the `current' shared state.
     *
     * @param o an existing Cancellation object from whom we get our
     * shared state.
     **/
    Cancellation& operator=(const Cancellation& o)
    {
        _d = o._d;
        return *this;
    }

    /**
     * Move constructor
     *
     * The new Cancellation will refer to the same shared state as `o'.
     *
     * @param o an existing Cancellation object from whom we get our
     * shared state.
     */
    Cancellation(Cancellation&& o) :
        _d(std::move(o._d))
    {}

    /**
     * Move operator
     *
     * On return, the new Cancellation will refer to the same shared
     * state as `o'. We will drop the reference to the `current' shared state.
     *
     * @param o an existing Cancellation object from whom we get our
     * shared state.
     */
    Cancellation& operator=(Cancellation&& o)
    {
        _d = std::move(o._d);
        return *this;
    }

    /**
     * Returns the current cancellation state of the object.
     *
     * It is generally not recommended that you use this function
     * because it is not thread-safe. Use hold_state(), instead.
     *
     * Once an object is Cancelled, this function returns `true'. Once
     * that happens, this function will never again return `false'.
     *
     * However, if this function returns `false' -- there's a
     * possibility that the object is actually Cancelled. Therefore
     * you should never rely on this value.
     *
     * @return true if the object has been cancelled. false if the
     * object has NOT been cancelled.
     */
    bool is_cancelled() const
    {
        return _d->is_cancelled();
    }

    /**
     * Set the state of the object to "cancelled"
     *
     * If the object is alread cancelled, this function returns
     * immediately.
     *
     * If not already cancelled, this function may block until all
     * state holds are released.
     */
    void cancel()
    {
        _d->cancel();
    }

    /**
     * Acquire a hold on the state of the object
     *
     * If the object is not not cancelled, the returned object will
     * prevent cancellation until it is deleted or released
     * (via. unlock()).
     *
     * If the object is cancelled, it returns immediately.
     *
     * You MUST check the validity of the returned lock. When cast to
     * bool, if it returns false then the object is cancelled.
     *
     * @return a CancellationStateLock object the prevents the state
     * of the object from changing.
     */
    CancellationStateLock hold_state() const FOLLY_CANCELLATION_WARN_UNUSED {
        CancellationStateLock lock(*_d, std::try_to_lock);
        return lock;
    }

private:
    std::shared_ptr<detail::CancellationSharedState> _d;
};

} /* namespace folly */
