#include <hn/fileslist.h>
#include <hn/sharedfile.h>
#include <hn/partdata.h>
// Test file size
static const uint32_t TESTSIZE = 1000000;

// Part 1: Create a new download.
void create_download() {
	// Step 1.1: Create PartData
	PartData *pd = new PartData(TESTSIZE, "TestFile.tmp");
	// Step 1.2: Assign a reference hash for the file.
	HashSet<MD5Hash> *hs = new HashSet<MD5Hash>(
		"67f90e8514ac105e831760e4030716bb"
	);
	MetaData *md = new MetaData(TESTSIZE);
	md->addHashSet(hs);
	md->addFileName("TestFile.tmp");
	MetaDb::instance().push(md);

	// Step 1.3: Create corresponding SharedFile
	SharedFile *sf = new SharedFile(pd);

	// Step 1.4: Give the entry to FilesList for containment.
	FilesList::instance().push(sf);
}

PartData* find_download() {
	Hash<MD4Hash> ref("67f90e8514ac105e831760e4030716bb");
	FileId id = MetaDb::instance().findId(ref);
	if (id == 0) {
		logError("Could not find our file from MetaDb! :(");
		return 0;
	}
	SharedFile *sf = FilesList::instance().find(id);
	if (sf == 0) {
		logError("Could not our file from FilesList! :(");
		return 0;
	}
	if (sf->isComplete()) {
		logError("The file is already complete.");
		return 0;
	}
	PartData *pd = sf->getPartData();
	if (pd == 0) {
		logError("SharedFile returned null pointer from getPartData()");
		return 0;
	}
	return pd;
}

void download_file(PartData *pd) {
	// Step 2.2: Retrieve a range to be downloaded. (1024 byte blocks plz)
	Range<> r = pd->getRandomRange(1024);
	DataRange<PartData::UsedRangeId> ur = pd->useRange(r);
	DataRange<PartData::LockedRangeId> lr = pd->lockRange(ur);
	char datastr[1024];
	for (uint32_t i = 0; i < 1024; ++i) {
		memcpy(&datastr[i], "1", 1);
	}
	const DataRange<char*, RMS::DataMergePolicy> data(
		lr.getBegin(), lr.getEnd(), datastr
	);
	pd->writeData(data, lr);
}

int main() {
	create_download();
	PartData *pd = find_download();
	if (pd == 0) {
		return false;
	}
	Hash<MD4Hash> ref("67f90e8514ac105e831760e4030716bb");
	FileId id = MetaDb::instance().findId(ref);
	while (!FilesList::instance().find(id)->isComplete()) {
		download_file(pd);
	}
}