#include <dlfcn.h>

#include "vmkit/system.h"
#include "vmkit/compiler.h"
#include "vmkit/thread.h"
#include "vmkit/vmkit.h"
#include "vmkit/safepoint.h"
#include "vmkit/inliner.h"

#include "llvm/LinkAllPasses.h"
#include "llvm/PassManager.h"

#include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/ExecutionEngine/JIT.h"

#include "llvm/Bitcode/ReaderWriter.h"

#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"

#include "llvm/Target/TargetOptions.h"

using namespace vmkit;

void* Symbol::getSymbolAddress() {
	Thread::get()->vm()->internalError("implement me: getSymbolAddress");
}

uint64_t Symbol::inlineWeight() {
	if(cachedWeight)
		return cachedWeight;

	if(llvmFunction()->size() > 4)
		return cachedWeight = (uint64_t)-1;

	uint64_t weight = 0;

	for (llvm::Function::iterator bit=llvmFunction()->begin(); bit!=llvmFunction()->end(); bit++)
		weight += bit->size();

	weight = weight * 256;

	return cachedWeight = weight;
}

void Symbol::markAsNeverInline() {
	if(llvmFunction())
		llvmFunction()->addFnAttr(llvm::Attribute::NoInline);
}

void* CompilationUnit::operator new(size_t n, BumpAllocator* allocator) {
	return allocator->allocate(n);
}

void  CompilationUnit::operator delete(void* self) {
}

CompilationUnit::CompilationUnit(BumpAllocator* allocator, const char* id, bool runInlinePass, bool onlyAlwaysInline) :
	_symbolTable(vmkit::Util::char_less, allocator) {
	_allocator = allocator;
	pthread_mutex_init(&_mutexSymbolTable, 0);

	std::string err;

	llvm::TargetOptions opt;
	opt.NoFramePointerElim = 1;

	_ee = llvm::EngineBuilder(new llvm::Module(id, Thread::get()->vm()->llvmContext()))
		.setUseMCJIT(1)
		.setMCJITMemoryManager(this)
		.setOptLevel(llvm::CodeGenOpt::None) /* Aggressive */
		.setTargetOptions(opt)
		.setErrorStr(&err)
		.create();

	if (!ee())
		Thread::get()->vm()->internalError("Error while creating execution engine: %s\n", err.c_str());

	ee()->finalizeObject();

	pm = new llvm::PassManager();
	//pm->add(new llvm::TargetData(*ee->getTargetData()));

#if 0
	pm->add(llvm::createBasicAliasAnalysisPass());
#endif

	if(runInlinePass || onlyAlwaysInline)
		pm->add(vmkit::createFunctionInlinerPass(this, onlyAlwaysInline));
	pm->add(llvm::createCFGSimplificationPass());      // Clean up disgusting code

#if 1
	pm->add(llvm::createPromoteMemoryToRegisterPass());// Kill useless allocas
	pm->add(llvm::createInstructionCombiningPass()); // Cleanup for scalarrepl.
	pm->add(llvm::createScalarReplAggregatesPass()); // Break up aggregate allocas
	pm->add(llvm::createInstructionCombiningPass()); // Cleanup for scalarrepl.
	pm->add(llvm::createJumpThreadingPass());        // Thread jumps.
	pm->add(llvm::createCFGSimplificationPass());    // Merge & remove BBs
	pm->add(llvm::createInstructionCombiningPass()); // Combine silly seq's
	pm->add(llvm::createCFGSimplificationPass());    // Merge & remove BBs

	pm->add(llvm::createReassociatePass());          // Reassociate expressions
	pm->add(llvm::createLoopRotatePass());           // Rotate loops.
	pm->add(llvm::createLICMPass());                 // Hoist loop invariants
	pm->add(llvm::createLoopUnswitchPass());         // Unswitch loops.
	pm->add(llvm::createInstructionCombiningPass());
	pm->add(llvm::createIndVarSimplifyPass());       // Canonicalize indvars
	pm->add(llvm::createLoopDeletionPass());         // Delete dead loops
	pm->add(llvm::createLoopUnrollPass());           // Unroll small loops*/
	pm->add(llvm::createInstructionCombiningPass()); // Clean up after the unroller
	pm->add(llvm::createGVNPass());                  // Remove redundancies
	pm->add(llvm::createMemCpyOptPass());            // Remove memcpy / form memset
	pm->add(llvm::createSCCPPass());                 // Constant prop with SCCP

	// Run instcombine after redundancy elimination to exploit opportunities
	// opened up by them.
	pm->add(llvm::createInstructionCombiningPass());
	pm->add(llvm::createJumpThreadingPass());         // Thread jumps
	pm->add(llvm::createDeadStoreEliminationPass());  // Delete dead stores
	pm->add(llvm::createAggressiveDCEPass());         // Delete dead instructions
	pm->add(llvm::createCFGSimplificationPass());     // Merge & remove BBs
#endif
}

CompilationUnit::~CompilationUnit() {
	delete pm;
	delete _ee;
}

void CompilationUnit::destroy(CompilationUnit* unit) {
	delete unit;
	BumpAllocator::destroy(unit->allocator());
}

void CompilationUnit::addSymbol(const char* id, vmkit::Symbol* symbol) {
	pthread_mutex_lock(&_mutexSymbolTable);
	_symbolTable[id] = symbol;
	pthread_mutex_unlock(&_mutexSymbolTable);
}

Symbol* CompilationUnit::getSymbol(const char* id, bool error) {
	pthread_mutex_lock(&_mutexSymbolTable);

	std::map<const char*, vmkit::Symbol*>::iterator it = _symbolTable.find(id);
	vmkit::Symbol* res = 0;

	if(it == _symbolTable.end()) {
		uint8_t* addr = (uint8_t*)dlsym(SELF_HANDLE, id);
		//fprintf(stderr, "lookup: %s => %p\n", id, addr);
		if(!addr) {
			if(error)
				Thread::get()->vm()->internalError("unable to resolve native symbol: %s", id);
		} else {
			res = new(allocator()) vmkit::NativeSymbol(0, addr);
			size_t len = strlen(id);
			char* buf = (char*)allocator()->allocate(len+1);
			memcpy(buf, id, len+1);
			_symbolTable[buf] = res;
		}
	} else
		res = it->second;

	pthread_mutex_unlock(&_mutexSymbolTable);

	return res;
}

uint64_t CompilationUnit::getSymbolAddress(const std::string &Name) {
	return (uint64_t)(uintptr_t)getSymbol(System::mcjitSymbol(Name.c_str()))->getSymbolAddress();
}

void CompilationUnit::compileModule(llvm::Module* module) {
	pm->run(*module);
	ee()->addModule(module);
	ee()->finalizeObject();

	vmkit::Safepoint* sf = Safepoint::get(this, module);
	VMKit* vm = Thread::get()->vm();

	if(!sf)
		vm->internalError("unable to find safepoints");
		
	while(sf->addr()) {
		sf->setUnit(this);
		vm->addSafepoint(sf);

		//Thread::get()->vm()->getSafepoint(sf->addr())->dump();
		sf = sf->getNext();
	}
}
