#include <stdio.h>
#include <string.h>
#include <errno.h>

#include "setup.h"

extern struct hash_backend hash_gcrypt_backend;

extern struct setup_backend setup_libdevmapper_backend;

static struct hash_backend *hash_backends[] = {
#if 1
	&hash_gcrypt_backend,
#endif
	NULL
};

static struct setup_backend *setup_backends[] = {
#if 1
	&setup_libdevmapper_backend,
#endif
	NULL
};

struct hash_backend *get_hash_backend(const char *name)
{
	struct hash_backend **backend;

	for(backend = hash_backends; *backend; backend++)
		if (!name || strcmp(name, (*backend)->name) == 0)
			break;

	return *backend;
}

void put_hash_backend(struct hash_backend *backend)
{
}

int hash(const char *backend_name, const char *hash_name,
         char *result, int size, const char *passphrase)
{
	struct hash_backend *backend;
	struct hash_type *hashes = NULL, *hash;
	int r = -ENOENT;

	backend = get_hash_backend(backend_name);
	if (!backend) {
		set_error("No hash backend found");
		return -ENOSYS;
	}

	hashes = backend->get_hashes();
	if (!hashes) {
		set_error("No hash functions available");
		goto out;
	}

	for(hash = hashes; hash->name; hash++)
		if (strcmp(hash->name, hash_name) == 0)
			break;
	if (!hash->name) {
		set_error("Unknown hash type %s", hash_name);
		goto out;
	}

	r = hash->fn(hash->private, size, result, passphrase);
	if (r < 0) {
		set_error("Error hashing passphrase");
		goto out;
	}

out:
	if (hashes)
		backend->free_hashes(hashes);
	put_hash_backend(backend);

	return r;
}

struct setup_backend *get_setup_backend(const char *name)
{
	struct setup_backend **backend;

	for(backend = setup_backends; *backend; backend++)
		if (!name || strcmp(name, (*backend)->name) == 0)
			break;

	return *backend;
}

void put_setup_backend(struct setup_backend *backend)
{
}
