#include "../../src/crypto/hash/md5.h"

#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstdio>

int test_md5_null() {
  md5 m;

  uint8_t expected[16] = {0xd4, 0x1d, 0x8c, 0xd9, 0x8f, 0x00, 0xb2, 0x04,
                          0xe9, 0x80, 0x09, 0x98, 0xec, 0xf8, 0x42, 0x7e};
  uint8_t actual[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  m.init();
  m.update(expected, 0);
  m.finalize(actual);

  for (int i = 0; i < 16; i++) {
    assert(actual[i] == expected[i]);
  }

  return 0;
}

int test_md5_foxdog() {
  md5 m;

  uint8_t expected[16] = {0x9e, 0x10, 0x7d, 0x9d, 0x37, 0x2b, 0xb6, 0x82,
                          0x6b, 0xd8, 0x1d, 0x35, 0x42, 0xa4, 0x19, 0xd6};
  uint8_t actual[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  unsigned char input[44] = "The quick brown fox jumps over the lazy dog";

  m.init();
  m.update((uint8_t *)input, 43);
  m.finalize(actual);

  for (int i = 0; i < 16; i++) {
    assert(actual[i] == expected[i]);
  }

  return 0;
}

int test_md5_foxdog_period() {
  md5 m;
  uint8_t expected[16] = {0xe4, 0xd9, 0x09, 0xc2, 0x90, 0xd0, 0xfb, 0x1c,
                          0xa0, 0x68, 0xff, 0xad, 0xdf, 0x22, 0xcb, 0xd0};
  uint8_t actual[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

  unsigned char input[45] = "The quick brown fox jumps over the lazy dog.";

  m.init();
  m.update((uint8_t *)input, 44);
  m.finalize(actual);

  for (int i = 0; i < 16; i++) {
    assert(actual[i] == expected[i]);
  }

  return 0;
}
