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

#ifdef ENABLE_RR_DEBUG_INFO

#include "Reactor.hpp"
#include "LLVMReactor.hpp"

#include "backtrace.h"

#include "llvm/Demangle/Demangle.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/IRBuilder.h"

#include <cctype>
#include <fstream>
#include <regex>
#include <sstream>
#include <string>

#if 0
#define LOG(msg, ...) printf(msg "\n", ##__VA_ARGS__)
#else
#define LOG(msg, ...)
#endif

namespace
{
	std::pair<llvm::StringRef, llvm::StringRef> splitPath(const char* path)
	{
		return llvm::StringRef(path).rsplit('/');
	}
} // anonymous namespaces

namespace rr
{
	DebugInfo::DebugInfo(
			llvm::IRBuilder<> *builder,
			llvm::LLVMContext *context,
			llvm::Module *module,
			llvm::Function *function)
		: builder(builder), context(context), module(module), function(function)
	{
		using namespace ::llvm;

		auto location = getCallerLocation();

		auto fileAndDir = splitPath(location.function.file.c_str());
		diBuilder = new llvm::DIBuilder(*module);
		diCU = diBuilder->createCompileUnit(
			llvm::dwarf::DW_LANG_C,
			diBuilder->createFile(fileAndDir.first, fileAndDir.second),
			"Reactor",
			0, "", 0);

		jitEventListener = llvm::JITEventListener::createGDBRegistrationListener();
		registerBasicTypes();

		SmallVector<Metadata *, 8> EltTys;
		auto funcTy = diBuilder->createSubroutineType(diBuilder->getOrCreateTypeArray(EltTys));

		auto file = getOrCreateFile(location.function.file.c_str());
		auto sp = diBuilder->createFunction(
			file,                   // scope
			"ReactorFunction",      // function name
			"ReactorFunction",      // linkage
			file,                   // file
			location.line,          // line
			funcTy,                 // type
			false,                  // internal linkage
			true,                   // definition
			location.line,          // scope line
			DINode::FlagPrototyped, // flags
			false                   // is optimized
		);
		diSubprogram = sp;
		function->setSubprogram(sp);
		diRootLocation = DILocation::get(*context, location.line, 0, sp);
		builder->SetCurrentDebugLocation(diRootLocation);
	}

	void DebugInfo::Finalize()
	{
		while (diScope.size() > 0)
		{
			emitPending(diScope.back(), builder, diBuilder);
			diScope.pop_back();
		}
		diBuilder->finalize();
	}

	void DebugInfo::EmitLocation()
	{
		auto const& backtrace = getCallerBacktrace();
		syncScope(backtrace);
		builder->SetCurrentDebugLocation(getLocation(backtrace, backtrace.size() - 1));
	}

	void DebugInfo::Flush()
	{
		emitPending(diScope.back(), builder, diBuilder);
	}

	void DebugInfo::syncScope(Backtrace const& backtrace)
	{
		auto shrink = [this](size_t newsize)
		{
			while (diScope.size() > newsize)
			{
				auto &scope = diScope.back();
				LOG("- STACK(%d): di: %p, location: %s:%d",
					int(diScope.size() - 1), scope.di,
					scope.location.function.file.c_str(),
					int(scope.location.line));
				emitPending(scope, builder, diBuilder);
				diScope.pop_back();
			}
		};

		if (backtrace.size() < diScope.size())
		{
			shrink(backtrace.size());
		}

		for (size_t i = 0; i < diScope.size(); i++)
		{
			auto &scope = diScope[i];
			auto const &oldLocation = scope.location;
			auto const &newLocation = backtrace[i];

			if (oldLocation.function != newLocation.function)
			{
				LOG("  STACK(%d): Changed function %s -> %s", int(i),
					oldLocation.function.name.c_str(), newLocation.function.name.c_str());
				shrink(i);
				break;
			}

			if (oldLocation.line > newLocation.line)
			{
				// Create a new di block to shadow all the variables in the loop.
				auto file = getOrCreateFile(newLocation.function.file.c_str());
				auto di = diBuilder->createLexicalBlock(scope.di, file, newLocation.line, 0);
				LOG("  STACK(%d): Jumped backwards %d -> %d. di: %p -> %p", int(i),
					oldLocation.line, newLocation.line, scope.di, di);
				emitPending(scope, builder, diBuilder);
				scope = {newLocation, di};
				shrink(i+1);
				break;
			}

			scope.location = newLocation;
		}

		while (backtrace.size() > diScope.size())
		{
			auto i = diScope.size();
			auto location = backtrace[i];
			auto file = getOrCreateFile(location.function.file.c_str());
			auto funcTy = diBuilder->createSubroutineType(diBuilder->getOrCreateTypeArray({}));

			char buf[1024];
			size_t size = sizeof(buf);
			int status = 0;
			llvm::itaniumDemangle(location.function.name.c_str(), buf, &size, &status);
			auto name = status == 0 ? buf : location.function.name.c_str();

			auto func = diBuilder->createFunction(
				file,                           // scope
				name,                           // function name
				"",                             // linkage
				file,                           // file
				location.line,                  // line
				funcTy,                         // type
				false,                          // internal linkage
				true,                           // definition
				location.line,                  // scope line
				llvm::DINode::FlagPrototyped,   // flags
				false                           // is optimized
			);
			diScope.push_back({location, func});
			LOG("+ STACK(%d): di: %p, location: %s:%d", int(i), di,
				location.function.file.c_str(), int(location.line));
		}
	}

	llvm::DILocation* DebugInfo::getLocation(const Backtrace &backtrace, size_t i)
	{
		if (backtrace.size() == 0) { return nullptr; }
		assert(backtrace.size() == diScope.size());
		return llvm::DILocation::get(
			*context,
			backtrace[i].line,
			0,
			diScope[i].di,
			i > 0 ? getLocation(backtrace, i - 1) : diRootLocation
		);
	}

	void DebugInfo::EmitVariable(Value *variable)
	{
		auto const& backtrace = getCallerBacktrace();
		syncScope(backtrace);

		for (int i = backtrace.size() - 1; i >= 0; i--)
		{
			auto const &location = backtrace[i];
			auto tokens = getOrParseFileTokens(location.function.file.c_str());
			auto tokIt = tokens->find(location.line);
			if (tokIt == tokens->end())
			{
				break;
			}
			auto token = tokIt->second;
			auto name = token.identifier;
			if (token.kind == Token::Return)
			{
				// This is a:
				//
				//   return <expr>;
				//
				// Emit this expression as two variables -
				// Once as a synthetic 'return_value' variable at this scope.
				// Again by bubbling the expression value up the callstack as
				// Return Value Optimizations (RVOs) are likely to carry across
				// the value to a local without calling a constructor in
				// statements like:
				//
				//   auto val = foo();
				//
				name = "return_value";
			}

			auto &scope = diScope[i];
			if (scope.pending.location != location)
			{
				emitPending(scope, builder, diBuilder);
			}

			auto value = V(variable);
			auto block = builder->GetInsertBlock();

			auto insertAfter = block->size() > 0 ? &block->back() : nullptr;
			while (insertAfter != nullptr && insertAfter->isTerminator())
			{
				insertAfter = insertAfter->getPrevNode();
			}

			scope.pending = Pending{};
			scope.pending.name = name;
			scope.pending.location = location;
			scope.pending.diLocation = getLocation(backtrace, i);
			scope.pending.value = value;
			scope.pending.block = block;
			scope.pending.insertAfter = insertAfter;
			scope.pending.scope = scope.di;

			if (token.kind == Token::Return)
			{
				// Insert a noop instruction so the debugger can inspect the
				// return value before the function scope closes.
				scope.pending.addNopOnNextLine = true;
			}
			else
			{
				break;
			}
		}
	}

	void DebugInfo::emitPending(Scope &scope, IRBuilder *builder, llvm::DIBuilder *diBuilder)
	{
		auto const &pending = scope.pending;
		if (pending.value == nullptr)
		{
			return;
		}

		if (!scope.symbols.emplace(pending.name).second)
		{
			return;
		}

		bool isAlloca = llvm::isa<llvm::AllocaInst>(pending.value);

		LOG("  EMIT(%s): di: %p, location: %s:%d, isAlloca: %s", pending.name.c_str(), scope.di,
			pending.location.function.file.c_str(), pending.location.line, isAlloca ? "true" : "false");

		auto value = pending.value;

		IRBuilder::InsertPointGuard guard(*builder);
		if (pending.insertAfter != nullptr)
		{
			builder->SetInsertPoint(pending.block, ++pending.insertAfter->getIterator());
		}
		else
		{
			builder->SetInsertPoint(pending.block);
		}
		builder->SetCurrentDebugLocation(pending.diLocation);

		if (!isAlloca)
		{
			// While insertDbgValueIntrinsic should be enough to declare a
			// variable with no storage, variables of RValues can share the same
			// llvm::Value, and only one can be named. Take for example:
			//
			//   Int a = 42;
			//   RValue<Int> b = a;
			//   RValue<Int> c = b;
			//
			// To handle this, always promote named RValues to an alloca.

			llvm::BasicBlock &entryBlock = function->getEntryBlock();
			auto alloca = new llvm::AllocaInst(value->getType(), 0, pending.name);
			entryBlock.getInstList().push_front(alloca);
			builder->CreateStore(value, alloca);
			value = alloca;
		}

		value->setName(pending.name);

		auto diFile = getOrCreateFile(pending.location.function.file.c_str());
		auto diType = getOrCreateType(value->getType()->getPointerElementType());
		auto diVar = diBuilder->createAutoVariable(scope.di, pending.name, diFile, pending.location.line, diType);

		auto di = diBuilder->insertDeclare(value, diVar, diBuilder->createExpression(), pending.diLocation, pending.block);
		if (pending.insertAfter != nullptr) { di->moveAfter(pending.insertAfter); }

		if (pending.addNopOnNextLine)
		{
			builder->SetCurrentDebugLocation(llvm::DILocation::get(
				*context,
				pending.diLocation->getLine() + 1,
				0,
				pending.diLocation->getScope(),
				pending.diLocation->getInlinedAt()
			));
			Nop();
		}

		scope.pending = Pending{};
	}

	void DebugInfo::NotifyObjectEmitted(const llvm::object::ObjectFile &Obj, const llvm::LoadedObjectInfo &L)
	{
		jitEventListener->NotifyObjectEmitted(Obj, static_cast<const llvm::RuntimeDyld::LoadedObjectInfo&>(L));
	}

	void DebugInfo::NotifyFreeingObject(const llvm::object::ObjectFile &Obj)
	{
		jitEventListener->NotifyFreeingObject(Obj);
	}

	void DebugInfo::registerBasicTypes()
	{
		using namespace rr;
		using namespace llvm;

		auto vec4 = diBuilder->getOrCreateArray(diBuilder->getOrCreateSubrange(0, 4));
		auto vec8 = diBuilder->getOrCreateArray(diBuilder->getOrCreateSubrange(0, 8));
		auto vec16 = diBuilder->getOrCreateArray(diBuilder->getOrCreateSubrange(0, 16));

		diTypes.emplace(T(Bool::getType()), diBuilder->createBasicType("Bool", sizeof(bool), dwarf::DW_ATE_boolean));
		diTypes.emplace(T(Byte::getType()), diBuilder->createBasicType("Byte", 8, dwarf::DW_ATE_unsigned_char));
		diTypes.emplace(T(SByte::getType()), diBuilder->createBasicType("SByte", 8, dwarf::DW_ATE_signed_char));
		diTypes.emplace(T(Short::getType()), diBuilder->createBasicType("Short", 16, dwarf::DW_ATE_signed));
		diTypes.emplace(T(UShort::getType()), diBuilder->createBasicType("UShort", 16, dwarf::DW_ATE_unsigned));
		diTypes.emplace(T(Int::getType()), diBuilder->createBasicType("Int", 32, dwarf::DW_ATE_signed));
		diTypes.emplace(T(UInt::getType()), diBuilder->createBasicType("UInt", 32, dwarf::DW_ATE_unsigned));
		diTypes.emplace(T(Long::getType()), diBuilder->createBasicType("Long", 64, dwarf::DW_ATE_signed));
		diTypes.emplace(T(Half::getType()), diBuilder->createBasicType("Half", 16, dwarf::DW_ATE_float));
		diTypes.emplace(T(Float::getType()), diBuilder->createBasicType("Float", 32, dwarf::DW_ATE_float));

		diTypes.emplace(T(Byte4::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Byte::getType())], {vec16}));
		diTypes.emplace(T(SByte4::getType()), diBuilder->createVectorType(128, 128, diTypes[T(SByte::getType())], {vec16}));
		diTypes.emplace(T(Byte8::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Byte::getType())], {vec16}));
		diTypes.emplace(T(SByte8::getType()), diBuilder->createVectorType(128, 128, diTypes[T(SByte::getType())], {vec16}));
		diTypes.emplace(T(Byte16::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Byte::getType())], {vec16}));
		diTypes.emplace(T(SByte16::getType()), diBuilder->createVectorType(128, 128, diTypes[T(SByte::getType())], {vec16}));
		diTypes.emplace(T(Short2::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Short::getType())], {vec8}));
		diTypes.emplace(T(UShort2::getType()), diBuilder->createVectorType(128, 128, diTypes[T(UShort::getType())], {vec8}));
		diTypes.emplace(T(Short4::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Short::getType())], {vec8}));
		diTypes.emplace(T(UShort4::getType()), diBuilder->createVectorType(128, 128, diTypes[T(UShort::getType())], {vec8}));
		diTypes.emplace(T(Short8::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Short::getType())], {vec8}));
		diTypes.emplace(T(UShort8::getType()), diBuilder->createVectorType(128, 128, diTypes[T(UShort::getType())], {vec8}));
		diTypes.emplace(T(Int2::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Int::getType())], {vec4}));
		diTypes.emplace(T(UInt2::getType()), diBuilder->createVectorType(128, 128, diTypes[T(UInt::getType())], {vec4}));
		diTypes.emplace(T(Int4::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Int::getType())], {vec4}));
		diTypes.emplace(T(UInt4::getType()), diBuilder->createVectorType(128, 128, diTypes[T(UInt::getType())], {vec4}));
		diTypes.emplace(T(Float2::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Float::getType())], {vec4}));
		diTypes.emplace(T(Float4::getType()), diBuilder->createVectorType(128, 128, diTypes[T(Float::getType())], {vec4}));
	}

	DebugInfo::Location DebugInfo::getCallerLocation() const
	{
		return getCallerBacktrace(1)[0];
	}

	DebugInfo::Backtrace DebugInfo::getCallerBacktrace(size_t limit /* = 0 */) const
	{
		struct callbacks
		{
			static void onError(void *data, const char *msg, int errnum)
			{
				fprintf(stderr, "BACKTRACE ERROR %d: %s\n", errnum, msg);
			}

			static int onPCInfo(void *data, uintptr_t pc, const char *file, int line, const char *function)
			{
				if (file == nullptr) { return 0; }

				auto const &fileSR = llvm::StringRef(file);
				if (fileSR.endswith("ReactorDebugInfo.cpp") ||
					fileSR.endswith("Reactor.cpp") ||
					fileSR.endswith("Reactor.hpp"))
				{
					return 0;
				}

				auto cb = reinterpret_cast<callbacks*>(data);

				Location location;
				location.function.file = file;
				location.function.name = function;
				location.line = line;

				cb->locations.push_back(location);
				return (cb->limit == 0 || sizeof(cb->locations) < cb->limit) ? 0 : 1;
			}

			size_t limit;
			std::vector<DebugInfo::Location> locations;
		};

		callbacks callbacks;
		callbacks.limit = limit;
		static auto state = backtrace_create_state(nullptr, 0, &callbacks::onError, nullptr);
		backtrace_full(state, 1, &callbacks::onPCInfo, &callbacks::onError, &callbacks);

		std::reverse(callbacks.locations.begin(), callbacks.locations.end());

		return callbacks.locations;
	}

	llvm::DIType *DebugInfo::getOrCreateType(llvm::Type* type)
	{
		auto it = diTypes.find(type);
		if (it != diTypes.end()) { return it->second; }

		if(type->isPointerTy())
		{
			auto dbgTy = diBuilder->createPointerType(
				getOrCreateType(type->getPointerElementType()),
				sizeof(void*)*8, alignof(void*)*8);
			diTypes.emplace(type, dbgTy);
			return dbgTy;
		}
		llvm::errs() << "Unimplemented debug type: " << type << "\n";
		assert(false);
	}

	llvm::DIFile *DebugInfo::getOrCreateFile(const char* path)
	{
		auto it = diFiles.find(path);
		if (it != diFiles.end()) { return it->second; }
		auto dirAndName = splitPath(path);
		auto file = diBuilder->createFile(dirAndName.second, dirAndName.first);
		diFiles.emplace(path, file);
		return file;
	}

	DebugInfo::LineTokens const *DebugInfo::getOrParseFileTokens(const char* path)
	{
		static std::regex reLocalDecl(
			"^" // line start
			"\\s*" // initial whitespace
			"(?:For\\s*\\(\\s*)?" // optional 'For ('
			"((?:\\w+(?:<[^>]+>)?)(?:::\\w+(?:<[^>]+>)?)*)" // type (match group 1)
			"\\s+" // whitespace between type and name
			"(\\w+)" // identifier (match group 2)
			"\\s*" // whitespace after identifier
			"(\\[.*\\])?"); // optional array suffix (match group 3)

		auto it = fileTokens.find(path);
		if (it != fileTokens.end())
		{
			return it->second.get();
		}

		auto tokens = std::unique_ptr<LineTokens>(new LineTokens());

		std::ifstream file(path);
		std::string line;
		int lineCount = 0;
		while (std::getline(file, line))
		{
			lineCount++;
			std::smatch match;
			if (std::regex_search(line, match, reLocalDecl) && match.size() > 3)
			{
				bool isArray = match.str(3) != "";
				if (!isArray) // Cannot deal with C-arrays of values.
				{
					if (match.str(1) == "return")
					{
						(*tokens)[lineCount] = Token{Token::Return};
					}
					else
					{
						(*tokens)[lineCount] = Token{Token::Identifier, match.str(2)};
					}
				}
			}
		}

		auto out = tokens.get();
		fileTokens.emplace(path, std::move(tokens));
		return out;
	}

} // namespace rr

#endif // ENABLE_RR_DEBUG_INFO
