// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// 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.

#ifndef VK_DEBUG_THREAD_HPP_
#define VK_DEBUG_THREAD_HPP_

#include "Context.hpp"
#include "ID.hpp"
#include "Location.hpp"

#include "marl/mutex.h"
#include "marl/tsa.h"

#include <condition_variable>
#include <memory>
#include <string>
#include <vector>

namespace vk {
namespace dbg {

class File;
class VariableContainer;
class ServerEventListener;

// Scope is a container for variables and is used to provide source data for the
// DAP 'Scope' type:
// https://microsoft.github.io/debug-adapter-protocol/specification#Types_Scope
class Scope
{
public:
	using ID = dbg::ID<Scope>;

	inline Scope(ID id,
	             const std::shared_ptr<File> &file,
	             const std::shared_ptr<VariableContainer> &variables);

	// The unique identifier of the scope.
	const ID id;

	// The file this scope is associated with.
	const std::shared_ptr<File> file;

	// The scope's variables.
	const std::shared_ptr<VariableContainer> variables;
};

Scope::Scope(ID id,
             const std::shared_ptr<File> &file,
             const std::shared_ptr<VariableContainer> &variables)
    : id(id)
    , file(file)
    , variables(variables)
{}

// Frame holds a number of variable scopes for one of a thread's stack frame,
// and is used to provide source data for the DAP 'StackFrame' type:
// https://microsoft.github.io/debug-adapter-protocol/specification#Types_StackFrame
class Frame
{
public:
	using ID = dbg::ID<Frame>;

	inline Frame(ID id, std::string function);

	// The unique identifier of the stack frame.
	const ID id;

	// The name of function for this stack frame.
	const std::string function;

	// The current execution location within the stack frame.
	Location location;

	// The scope for the frame's arguments.
	std::shared_ptr<Scope> arguments;

	// The scope for the frame's locals.
	std::shared_ptr<Scope> locals;

	// The scope for the frame's registers.
	std::shared_ptr<Scope> registers;

	// The scope for variables that should only appear in hover tooltips.
	std::shared_ptr<Scope> hovers;
};

Frame::Frame(ID id, std::string function)
    : id(id)
    , function(std::move(function))
{}

// Thread holds the state for a single thread of execution.
class Thread
{
public:
	using ID = dbg::ID<Thread>;

	using UpdateFrame = std::function<void(Frame &)>;

	// The current execution state.
	enum class State
	{
		Running,   // Thread is running.
		Stepping,  // Thread is currently single line stepping.
		Paused     // Thread is currently paused.
	};

	Thread(ID id, Context *ctx);

	// setName() sets the name of the thread.
	void setName(const std::string &);

	// name() returns the name of the thread.
	std::string name() const;

	// enter() pushes the thread's stack with a new frame created with the given
	// file and function, then calls f to modify the new frame of the stack.
	void enter(const std::shared_ptr<File> &file, const std::string &function, const UpdateFrame &f = nullptr);

	// exit() pops the thread's stack frame.
	void exit();

	// frame() returns a copy of the thread's top most stack frame.
	Frame frame() const;

	// stack() returns a copy of the thread's current stack frames.
	std::vector<Frame> stack() const;

	// depth() returns the number of stack frames.
	size_t depth() const;

	// state() returns the current thread's state.
	State state() const;

	// update() calls f to modify the top most frame of the stack.
	// If the frame's location is changed and isStep is true, update()
	// potentially blocks until the thread is resumed with one of the methods
	// below.
	// isStep is used to distinguish same-statement column position updates
	// from full line updates. Note that we cannot simply examine line position
	// changes as single-line loops such as `while(true) { foo(); }` would not
	// be correctly steppable.
	void update(bool isStep, const UpdateFrame &f);

	// resume() resumes execution of the thread by unblocking a call to
	// update() and setting the thread's state to State::Running.
	void resume();

	// pause() suspends execution of the thread by blocking the next call to
	// update() and setting the thread's state to State::Paused.
	void pause();

	// stepIn() temporarily resumes execution of the thread by unblocking a
	// call to update(), and setting the thread's state to State::Stepping.
	// The next call to update() will suspend execution again.
	void stepIn();

	// stepOver() temporarily resumes execution of the thread by unblocking a
	// call to update(), and setting the thread's state to State::Stepping.
	// The next call to update() within the same stack frame will suspend
	// execution again.
	void stepOver();

	// stepOut() temporarily resumes execution of the thread by unblocking a
	// call to update(), and setting the thread's state to State::Stepping.
	// The next call to update() at the stack frame above the current frame will
	// suspend execution again.
	void stepOut();

	// The unique identifier of the thread.
	const ID id;

private:
	Context *const ctx;

	void onLocationUpdate(marl::lock &lock) REQUIRES(mutex);

	mutable marl::mutex mutex;
	std::string name_ GUARDED_BY(mutex);
	std::vector<std::shared_ptr<Frame>> frames GUARDED_BY(mutex);
	State state_ GUARDED_BY(mutex) = State::Running;
	std::weak_ptr<Frame> pauseAtFrame GUARDED_BY(mutex);

	std::condition_variable stateCV;
};

}  // namespace dbg
}  // namespace vk

#endif  // VK_DEBUG_THREAD_HPP_
