/* GNU Guix --- Functional package management for GNU
   Copyright © 2020 Maxime Devos <maxime.devos@student.kuleuven.be>

   This file is part of GNU Guix.

   GNU Guix is free software; you can redistribute it and/or modify it
   under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or (at
   your option) any later version.

   GNU Guix is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with GNU Guix.  If not, see <http://www.gnu.org/licenses/>. */

#include <gnunet/gnunet_config.h>
#include <stdint.h>
#include <string.h>
#include "rehash_types.h"
#include "rehash_util.h"
#include "fs_api.h"

static const int hash_lengths[] = {
  [GNUNET_REHASH_HASH_NONE] = 0,
  [GNUNET_REHASH_HASH_SHA256] = 32,
  [GNUNET_REHASH_HASH_SHA512] = 64,
  [GNUNET_REHASH_HASH_SHA3_256] = 32,
  [GNUNET_REHASH_HASH_SHA3_512] = 64,
  /* TODO check */
  [GNUNET_REHASH_HASH_BLAKE2S_256] = 32,
  /* */
  [GNUNET_REHASH_HASH_FS_REGULAR] = sizeof(struct FileIdentifier),
};

static const char hash_names[][12] = {
  [GNUNET_REHASH_HASH_SHA256]      = "sha256",
  [GNUNET_REHASH_HASH_SHA512]      = "sha512",
  [GNUNET_REHASH_HASH_SHA3_256]    = "sha3-256",
  [GNUNET_REHASH_HASH_SHA3_512]    = "sha3-512",
  [GNUNET_REHASH_HASH_BLAKE2S_256] = "blake2s-256",
  [GNUNET_REHASH_HASH_FS_REGULAR]  = "fs-regular",
};

int
GNUNET_REHASH_hashtype_strsize (enum GNUNET_REHASH_Hash_Type type)
{
  int index;
  index = type > GNUNET_REHASH_HASH_LAST ? 0 : (int) type;
  return hash_lengths[index];
}

int
GNUNET_REHASH_unparse_hashtype (enum GNUNET_REHASH_Hash_Type type, int size, char outbuf[])
{
  if ((type == GNUNET_REHASH_HASH_NONE) || (type > GNUNET_REHASH_HASH_LAST))
    return 0;
  strncpy(outbuf, hash_names[type], size);
  return size;
}

enum GNUNET_REHASH_Hash_Type
GNUNET_REHASH_parse_hashtype (const char *name)
{
  enum GNUNET_REHASH_Hash_Type candidate;
  for (candidate = 1; candidate <= GNUNET_REHASH_HASH_LAST; candidate++)
  {
    if (0 == strcmp(name, hash_names[(int) candidate]))
      return candidate;
  }
  return GNUNET_REHASH_HASH_NONE;
}
