#include "test_util.h"
#include <fstream>
#include <stdexcept>
#include <string>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

namespace bdm {

std::string load_test_file(const char *fname)
{
    char buffer[8192];
    memset(buffer, 0, sizeof(buffer));
    std::ifstream src(fname, std::ios_base::binary);
    src.read(buffer, sizeof(buffer) - 1);
    return std::string(buffer);
}

bool remove_all(const char *path) {
    DIR *dir;
    dirent *de;

    bool rv = true;
    if ((dir = opendir(path)) != 0) {
        try {
	    std::string top(path);
	    top += "/";

	    while ((de = readdir(dir)) != 0) {
		if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) {
		    std::string subpath(top);
		    subpath += de->d_name;
		    remove_all(subpath.c_str());
		}
	    }
	} catch (...) {
	    closedir(dir);
	    throw;
	}

	closedir(dir);

	if (rmdir(path)) {
	    std::string msg = "can't remove dir ";
	    msg += path;
	    throw std::runtime_error(msg);
	}
    } else { 
        if (errno == ENOTDIR) {
	    if (unlink(path)) {
  	        std::string msg = "can't remove file ";
		msg += path;
		throw std::runtime_error(msg);
	    }
	} else {
	    if (errno != ENOENT) {
	        std::string msg = "can't remove ";
		msg += path;
		throw std::runtime_error(msg);
	    } else {
	        // it wasn't there in the first place
	        rv = false;
	    }
	}
    }

    return rv;
}

}
