// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <atomic>
#include <fbl/function.h>
#include <fbl/futex.h>
#include <fbl/macros.h>
#include <lib/zx/channel.h>
#include <lib/zx/thread.h>
#include <zircon/assert.h>
#include <zircon/syscalls.h>
#include <zircon/threads.h>
#include <zircon/types.h>

// Allow up to 4 pointers worth of storage for any lambdas we need to capture
// into a fbl::InlineFunction object (instead of falling back on the implicit
// heap allocation behavior of fbl::Function or std::function)
static constexpr size_t kMaxLambdaStorage = sizeof(void*) * 4;

// A small helper which allows us to poll with a timeout for a condition to
// become true.  Sadly, some of the futex-ownership tests require this as there
// is no opportunity for a thread which has become blocked on a futex to signal
// another thread without unblocking.  When testing the state of the system
// while we have a thread blocked via zx_futex_wait, the best we can do is have
// the thread give us a signal, and then wait a "reasonable" amount of time for
// the system to achieve the desired state (or not).
using WaitFn = fbl::InlineFunction<bool(void), kMaxLambdaStorage>;
bool WaitFor(zx_duration_t timeout, WaitFn wait_fn);

// A small helper which fetches the Koid for the current thread.
zx_koid_t CurrentThreadKoid();

// A lightweight signal based on an unowned futex which can be used to
// block/unblock threads.  Used extensively in the futex ownership tests for
// sequencing thread behavior which would typically just be a bunch of timing
// races in real code.
class Event {
public:
    Event() = default;
    DISALLOW_COPY_ASSIGN_AND_MOVE(Event);

    zx_status_t Wait(zx_duration_t timeout);
    void Signal();
    void Reset();

private:
    fbl::futex_t signaled_ = {0};
};

// A lightweight wrapper for threads which allow us to create threads and have
// then run a quick lambda, while automating much of the boilerplate we need for
// the ownership tests (things like fetching a thread's KOID)
class Thread {
  public:
    using Thunk = fbl::InlineFunction<int(void), kMaxLambdaStorage>;

    enum class State : uint32_t {
        WAITING_TO_START,
        RUNNING,
        WAITING_TO_STOP,
        STOPPED,
    };

    Thread() { Reset(); }
    DISALLOW_COPY_ASSIGN_AND_MOVE(Thread);

    bool Start(const char* name, Thunk thunk);
    zx_status_t Stop();
    zx_status_t GetRunState(uint32_t* run_state) const;

    const zx::thread& handle() const { return handle_; }
    zx_koid_t koid() const { return koid_; }
    State state() const { return state_.load(); }

  private:
    static constexpr zx_duration_t THREAD_TIMEOUT = ZX_MSEC(1000);
    static constexpr zx_duration_t THREAD_POLL_INTERVAL = ZX_MSEC(1);

    void SetState(State state) {
        state_.store(state);
    }

    void Reset();

    thrd_t thread_;
    zx::thread handle_;
    zx_koid_t koid_;
    Event started_evt_;
    Event stop_evt_;
    std::atomic<State> state_{State::STOPPED};
    Thunk thunk_;
};

// A small wrapper used to launch a process which creates a thread and sends us
// a handle to the thread, then waits until we tell it to terminate.  This
// allows us to test the requirement that a process is not allowed to declare a
// thread from another process as the owner of one of its mutexes.
class ExternalThread {
public:
    static void SetProgramName(const char* program_name) { program_name_ = program_name; }
    static int DoHelperThread();
    static const char* helper_flag() { return helper_flag_; }

    ExternalThread() = default;
    ~ExternalThread() { Stop(); }
    DISALLOW_COPY_ASSIGN_AND_MOVE(ExternalThread);

    bool Start();
    void Stop();

    const zx::thread& thread() const { return external_thread_; }

private:
    static const char* program_name_;
    static const char* helper_flag_;

    zx::thread external_thread_;
    zx::channel control_channel_;
};
