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