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

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

int test_sha1_null() {
  sha1 m;

  uint8_t expected[20] = {0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
                          0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09};
  uint8_t actual[20] = {0x00, 0x00, 0x00, 0x00, 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_sha1_foxdog() {
  sha1 m;

  uint8_t expected[20] = {0x2f, 0xd4, 0xe1, 0xc6, 0x7a, 0x2d, 0x28, 0xfc, 0xed, 0x84,
                          0x9e, 0xe1, 0xbb, 0x76, 0xe7, 0x39, 0x1b, 0x93, 0xeb, 0x12};
  uint8_t actual[20] = {0x00, 0x00, 0x00, 0x00, 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_sha1_foxdog_period() {
  sha1 m;

  uint8_t expected[20] = {0x40, 0x8d, 0x94, 0x38, 0x42, 0x16, 0xf8, 0x90, 0xff, 0x7a,
                          0x0c, 0x35, 0x28, 0xe8, 0xbe, 0xd1, 0xe0, 0xb0, 0x16, 0x21};
  uint8_t actual[20] = {0x00, 0x00, 0x00, 0x00, 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;
}
