// 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 "Context.hpp"

#include "EventListener.hpp"
#include "File.hpp"
#include "Thread.hpp"
#include "Variable.hpp"
#include "WeakMap.hpp"

#include <memory>
#include <mutex>
#include <thread>
#include <unordered_map>
#include <unordered_set>

#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
#	define CHECK_REENTRANT_CONTEXT_LOCKS 1
#else
#	define CHECK_REENTRANT_CONTEXT_LOCKS 0
#endif

namespace {

#if CHECK_REENTRANT_CONTEXT_LOCKS
thread_local std::unordered_set<const void *> contextsWithLock;
#endif

////////////////////////////////////////////////////////////////////////////////
// Broadcaster - template base class for ServerEventBroadcaster and
// ClientEventBroadcaster
////////////////////////////////////////////////////////////////////////////////
template<typename Listener>
class Broadcaster : public Listener
{
public:
	void add(Listener *);
	void remove(Listener *);

protected:
	template<typename F>
	inline void foreach(F &&);

	template<typename F>
	inline void modify(F &&);

	using ListenerSet = std::unordered_set<Listener *>;
	std::recursive_mutex mutex;
	std::shared_ptr<ListenerSet> listeners = std::make_shared<ListenerSet>();
	int listenersInUse = 0;
};

template<typename Listener>
void Broadcaster<Listener>::add(Listener *l)
{
	modify([&]() { listeners->emplace(l); });
}

template<typename Listener>
void Broadcaster<Listener>::remove(Listener *l)
{
	modify([&]() { listeners->erase(l); });
}

template<typename Listener>
template<typename F>
void Broadcaster<Listener>::foreach(F &&f)
{
	std::unique_lock<std::recursive_mutex> lock(mutex);
	++listenersInUse;
	auto copy = listeners;
	for(auto l : *copy) { f(l); }
	--listenersInUse;
}

template<typename Listener>
template<typename F>
void Broadcaster<Listener>::modify(F &&f)
{
	std::unique_lock<std::recursive_mutex> lock(mutex);
	if(listenersInUse > 0)
	{
		// The listeners map is current being iterated over.
		// Make a copy before making the edit.
		listeners = std::make_shared<ListenerSet>(*listeners);
	}
	f();
}

////////////////////////////////////////////////////////////////////////////////
// ServerEventBroadcaster
////////////////////////////////////////////////////////////////////////////////
class ServerEventBroadcaster : public Broadcaster<vk::dbg::ServerEventListener>
{
public:
	using Thread = vk::dbg::Thread;

	void onThreadStarted(Thread::ID id) override
	{
		foreach([&](auto *l) { l->onThreadStarted(id); });
	}

	void onThreadStepped(Thread::ID id) override
	{
		foreach([&](auto *l) { l->onThreadStepped(id); });
	}

	void onLineBreakpointHit(Thread::ID id) override
	{
		foreach([&](auto *l) { l->onLineBreakpointHit(id); });
	}

	void onFunctionBreakpointHit(Thread::ID id) override
	{
		foreach([&](auto *l) { l->onFunctionBreakpointHit(id); });
	}
};

////////////////////////////////////////////////////////////////////////////////
// ClientEventBroadcaster
////////////////////////////////////////////////////////////////////////////////
class ClientEventBroadcaster : public Broadcaster<vk::dbg::ClientEventListener>
{
public:
	void onSetBreakpoint(const vk::dbg::Location &location, bool &handled) override
	{
		foreach([&](auto *l) { l->onSetBreakpoint(location, handled); });
	}

	void onSetBreakpoint(const std::string &func, bool &handled) override
	{
		foreach([&](auto *l) { l->onSetBreakpoint(func, handled); });
	}

	void onBreakpointsChanged() override
	{
		foreach([&](auto *l) { l->onBreakpointsChanged(); });
	}
};

}  // namespace

namespace vk {
namespace dbg {

////////////////////////////////////////////////////////////////////////////////
// Context::Impl
////////////////////////////////////////////////////////////////////////////////
class Context::Impl : public Context
{
public:
	// Context compliance
	Lock lock() override;
	void addListener(ClientEventListener *) override;
	void removeListener(ClientEventListener *) override;
	ClientEventListener *clientEventBroadcast() override;
	void addListener(ServerEventListener *) override;
	void removeListener(ServerEventListener *) override;
	ServerEventListener *serverEventBroadcast() override;

	void addFile(const std::shared_ptr<File> &file);

	ServerEventBroadcaster serverEventBroadcaster;
	ClientEventBroadcaster clientEventBroadcaster;

	std::mutex mutex;
	std::unordered_map<std::thread::id, std::shared_ptr<Thread>> threadsByStdId;
	std::unordered_set<std::string> functionBreakpoints;
	std::unordered_map<std::string, std::vector<int>> pendingBreakpoints;
	WeakMap<Thread::ID, Thread> threads;
	WeakMap<File::ID, File> files;
	WeakMap<Frame::ID, Frame> frames;
	WeakMap<Scope::ID, Scope> scopes;
	WeakMap<Variables::ID, Variables> variables;
	Thread::ID nextThreadID = 1;
	File::ID nextFileID = 1;
	Frame::ID nextFrameID = 1;
	Scope::ID nextScopeID = 1;
};

Context::Lock Context::Impl::lock()
{
	return Lock(this);
}

void Context::Impl::addListener(ClientEventListener *l)
{
	clientEventBroadcaster.add(l);
}

void Context::Impl::removeListener(ClientEventListener *l)
{
	clientEventBroadcaster.remove(l);
}

ClientEventListener *Context::Impl::clientEventBroadcast()
{
	return &clientEventBroadcaster;
}

void Context::Impl::addListener(ServerEventListener *l)
{
	serverEventBroadcaster.add(l);
}

void Context::Impl::removeListener(ServerEventListener *l)
{
	serverEventBroadcaster.remove(l);
}

ServerEventListener *Context::Impl::serverEventBroadcast()
{
	return &serverEventBroadcaster;
}

void Context::Impl::addFile(const std::shared_ptr<File> &file)
{
	files.add(file->id, file);

	auto it = pendingBreakpoints.find(file->name);
	if(it != pendingBreakpoints.end())
	{
		for(auto line : it->second)
		{
			file->addBreakpoint(line);
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
// Context
////////////////////////////////////////////////////////////////////////////////
std::shared_ptr<Context> Context::create()
{
	return std::shared_ptr<Context>(new Context::Impl());
}

////////////////////////////////////////////////////////////////////////////////
// Context::Lock
////////////////////////////////////////////////////////////////////////////////
Context::Lock::Lock(Impl *ctx)
    : ctx(ctx)
{
#if CHECK_REENTRANT_CONTEXT_LOCKS
	ASSERT_MSG(contextsWithLock.count(ctx) == 0, "Attempting to acquire Context lock twice on same thread. This will deadlock");
	contextsWithLock.emplace(ctx);
#endif
	ctx->mutex.lock();
}

Context::Lock::Lock(Lock &&o)
    : ctx(o.ctx)
{
	o.ctx = nullptr;
}

Context::Lock::~Lock()
{
	unlock();
}

Context::Lock &Context::Lock::operator=(Lock &&o)
{
	ctx = o.ctx;
	o.ctx = nullptr;
	return *this;
}

void Context::Lock::unlock()
{
	if(ctx)
	{
#if CHECK_REENTRANT_CONTEXT_LOCKS
		contextsWithLock.erase(ctx);
#endif

		ctx->mutex.unlock();
		ctx = nullptr;
	}
}

std::shared_ptr<Thread> Context::Lock::currentThread()
{
	auto threadIt = ctx->threadsByStdId.find(std::this_thread::get_id());
	if(threadIt != ctx->threadsByStdId.end())
	{
		return threadIt->second;
	}
	auto id = ++ctx->nextThreadID;
	char name[256];
	snprintf(name, sizeof(name), "Thread<0x%x>", id.value());

	auto thread = std::make_shared<Thread>(id, ctx);
	ctx->threads.add(id, thread);
	thread->setName(name);
	ctx->threadsByStdId.emplace(std::this_thread::get_id(), thread);

	ctx->serverEventBroadcast()->onThreadStarted(id);

	return thread;
}

std::shared_ptr<Thread> Context::Lock::get(Thread::ID id)
{
	return ctx->threads.get(id);
}

std::vector<std::shared_ptr<Thread>> Context::Lock::threads()
{
	std::vector<std::shared_ptr<Thread>> out;
	out.reserve(ctx->threads.approx_size());
	for(auto it : ctx->threads)
	{
		out.push_back(it.second);
	}
	return out;
}

std::shared_ptr<File> Context::Lock::createVirtualFile(const std::string &name,
                                                       const std::string &source)
{
	auto file = File::createVirtual(ctx->nextFileID++, name, source);
	ctx->addFile(file);
	return file;
}

std::shared_ptr<File> Context::Lock::createPhysicalFile(const std::string &path)
{
	auto file = File::createPhysical(ctx->nextFileID++, path);
	ctx->addFile(file);
	return file;
}

std::shared_ptr<File> Context::Lock::get(File::ID id)
{
	return ctx->files.get(id);
}

std::vector<std::shared_ptr<File>> Context::Lock::files()
{
	std::vector<std::shared_ptr<File>> out;
	out.reserve(ctx->files.approx_size());
	for(auto it : ctx->files)
	{
		out.push_back(it.second);
	}
	return out;
}

std::shared_ptr<Frame> Context::Lock::createFrame(
    const std::shared_ptr<File> &file, std::string function)
{
	auto frame = std::make_shared<Frame>(ctx->nextFrameID++, std::move(function));
	ctx->frames.add(frame->id, frame);
	frame->arguments = createScope(file);
	frame->locals = createScope(file);
	frame->registers = createScope(file);
	frame->hovers = createScope(file);
	return frame;
}

std::shared_ptr<Frame> Context::Lock::get(Frame::ID id)
{
	return ctx->frames.get(id);
}

std::shared_ptr<Scope> Context::Lock::createScope(
    const std::shared_ptr<File> &file)
{
	auto scope = std::make_shared<Scope>(ctx->nextScopeID++, file, std::make_shared<VariableContainer>());
	ctx->scopes.add(scope->id, scope);
	return scope;
}

std::shared_ptr<Scope> Context::Lock::get(Scope::ID id)
{
	return ctx->scopes.get(id);
}

void Context::Lock::track(const std::shared_ptr<Variables> &vars)
{
	ctx->variables.add(vars->id, vars);
}

std::shared_ptr<Variables> Context::Lock::get(Variables::ID id)
{
	return ctx->variables.get(id);
}

void Context::Lock::addFunctionBreakpoint(const std::string &name)
{
	ctx->functionBreakpoints.emplace(name);
}

void Context::Lock::addPendingBreakpoints(const std::string &filename, const std::vector<int> &lines)
{
	ctx->pendingBreakpoints.emplace(filename, lines);
}

bool Context::Lock::isFunctionBreakpoint(const std::string &name)
{
	return ctx->functionBreakpoints.count(name) > 0;
}

}  // namespace dbg
}  // namespace vk
