// 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.

#include "Thread.hpp"

#include "Context.hpp"
#include "EventListener.hpp"
#include "File.hpp"

namespace vk {
namespace dbg {

Thread::Thread(ID id, Context *ctx)
    : id(id)
    , broadcast(ctx->broadcast())
{}

void Thread::setName(const std::string &name)
{
	std::unique_lock<std::mutex> lock(mutex);
	name_ = name;
}

std::string Thread::name() const
{
	std::unique_lock<std::mutex> lock(mutex);
	return name_;
}

void Thread::update(const Location &location)
{
	std::unique_lock<std::mutex> lock(mutex);
	frames.back()->location = location;

	if(state_ == State::Running)
	{
		if(location.file->hasBreakpoint(location.line))
		{
			broadcast->onLineBreakpointHit(id);
			state_ = State::Paused;
		}
	}

	switch(state_)
	{
		case State::Paused:
		{
			stateCV.wait(lock, [this] { return state_ != State::Paused; });
			break;
		}

		case State::Stepping:
		{
			if(!pauseAtFrame || pauseAtFrame == frames.back())
			{
				broadcast->onThreadStepped(id);
				state_ = State::Paused;
				stateCV.wait(lock, [this] { return state_ != State::Paused; });
				pauseAtFrame = 0;
			}
			break;
		}

		case State::Running:
			break;
	}
}

void Thread::enter(Context::Lock &ctxlck, const std::shared_ptr<File> &file, const std::string &function)
{
	auto frame = ctxlck.createFrame(file);
	auto isFunctionBreakpoint = ctxlck.isFunctionBreakpoint(function);

	std::unique_lock<std::mutex> lock(mutex);
	frame->function = function;
	frames.push_back(frame);
	if(isFunctionBreakpoint)
	{
		broadcast->onFunctionBreakpointHit(id);
		state_ = State::Paused;
	}
}

void Thread::exit()
{
	std::unique_lock<std::mutex> lock(mutex);
	frames.pop_back();
}

std::shared_ptr<VariableContainer> Thread::registers() const
{
	std::unique_lock<std::mutex> lock(mutex);
	return frames.back()->registers->variables;
}

std::shared_ptr<VariableContainer> Thread::locals() const
{
	std::unique_lock<std::mutex> lock(mutex);
	return frames.back()->locals->variables;
}

std::shared_ptr<VariableContainer> Thread::arguments() const
{
	std::unique_lock<std::mutex> lock(mutex);
	return frames.back()->arguments->variables;
}

std::shared_ptr<VariableContainer> Thread::hovers() const
{
	std::unique_lock<std::mutex> lock(mutex);
	return frames.back()->hovers->variables;
}

std::vector<Frame> Thread::stack() const
{
	std::unique_lock<std::mutex> lock(mutex);
	std::vector<Frame> out;
	out.reserve(frames.size());
	for(auto frame : frames)
	{
		out.push_back(*frame);
	}
	return out;
}

Thread::State Thread::state() const
{
	std::unique_lock<std::mutex> lock(mutex);
	return state_;
}

void Thread::resume()
{
	std::unique_lock<std::mutex> lock(mutex);
	state_ = State::Running;
	lock.unlock();
	stateCV.notify_all();
}

void Thread::pause()
{
	std::unique_lock<std::mutex> lock(mutex);
	state_ = State::Paused;
}

void Thread::stepIn()
{
	std::unique_lock<std::mutex> lock(mutex);
	state_ = State::Stepping;
	pauseAtFrame.reset();
	stateCV.notify_all();
}

void Thread::stepOver()
{
	std::unique_lock<std::mutex> lock(mutex);
	state_ = State::Stepping;
	pauseAtFrame = frames.back();
	stateCV.notify_all();
}

void Thread::stepOut()
{
	std::unique_lock<std::mutex> lock(mutex);
	state_ = State::Stepping;
	pauseAtFrame = (frames.size() > 1) ? frames[frames.size() - 1] : nullptr;
	stateCV.notify_all();
}

}  // namespace dbg
}  // namespace vk