#include "Utils.h"

#include <iostream>
#include <string>
#include <fstream>

#include <boost/filesystem.hpp>
#include <cstdlib>

#include <sha2.h>

std::string strip_whitespaces (const std::string input_str) {
	if (input_str.size() == 0)
		return input_str;

	std::string result = input_str.substr(input_str.find_first_not_of (" \t\n\r"), input_str.size());
	return result.substr (0, result.find_last_not_of(" \t\n\r") + 1);
}

bool create_dir (const std::string &dir_str) {
	boost::filesystem::path dir_str_path(dir_str);
	if(!boost::filesystem::is_directory (dir_str_path)) {
		if (!boost::filesystem::create_directory(dir_str_path)) {
			std::cerr << "Warning: could not create directory " << dir_str<< std::endl;
			return false;
		}
	}

	std::string test_file_path = dir_str;
	test_file_path += "/fysxasteroids_write_test_delete_me.txt";
	std::ofstream test_file (test_file_path.c_str(), std::ios_base::app);
	if (!test_file) {
		test_file.close();
		std::cerr << "Warning: directory not writable! " << dir_str << std::endl;
		return false;
	} else {
		test_file.close();
		boost::filesystem::remove (test_file_path);
		return true;
	}

	return false;
}

std::string sha256_hash (std::string input) {
	char result_buf[65];
	result_buf[64] = '\0';

	SHA256_CTX ctx256;

	SHA256_Init(&ctx256);
	SHA256_Update(&ctx256, (unsigned char*) input.c_str(), input.size());
	SHA256_End (&ctx256, result_buf);

	return std::string (result_buf);
}

std::string sha256_hash_file (const char *filename) {
	// we simply read the whole file into a string and hash this
	std::ifstream file_stream (filename, std::ios_base::binary);
	if (!file_stream.is_open()) {
		std::cerr << "Could not hash file " << filename << ": could not open file." << std::endl;
		return "";
	}

	file_stream.seekg (0,std::ios_base::end);
	std::streampos file_end = file_stream.tellg();

	int file_size = static_cast<int> (file_end);
	if (file_size == 0) {
		std::cerr << "Could not hash file " << filename << ": file has no content!" << std::endl;
		return "";
	}

	unsigned char *file_buffer = NULL;
	file_buffer = new unsigned char[file_size];

	file_stream.seekg(0, std::ios_base::beg);
	file_stream.read ((char*)file_buffer, file_size);

	char result_buf[65];

	SHA256_CTX ctx256;

	SHA256_Init(&ctx256);
	SHA256_Update(&ctx256, file_buffer, file_size);
	SHA256_End (&ctx256, result_buf);

	file_stream.close();

	delete[] file_buffer;

	result_buf[64] = '\0';

//	std::cerr << "file hash is " << std::string (result_buf, 64) << std::endl;

	return std::string (result_buf, 64);
}

