#ifdef NDEBUG
#undef NDEBUG
#endif

#include <assert.h>
#include <errno.h>
#include <locale.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

static void set_conversion_state (mbstate_t *state, int bytes) {
#ifdef _UCRT
  state->_Wchar = bytes;
#else
  *state = bytes;
#endif
}

int main (void) {
#ifdef _UCRT
  return 77;
#endif
  mbstate_t state = {0};

  /**
   * Test "C" locale
   */
  assert (setlocale (LC_ALL, "C") != NULL);
  assert (MB_CUR_MAX == 1);

  /**
   * All values in range [0,255] are valid and must convert to themselves
   */
  for (wchar_t wc = 0; wc < 0x100; ++wc) {
    char c = EOF;

    assert (wcrtomb (&c, wc, &state) == 1);
    assert ((unsigned char) c == wc);
    assert (errno == 0);
    assert (mbsinit (&state));
  }

  /**
   * Detect invalid conversion state
   *
   * NOTE: this is optional error condition specified in POSIX.
   * This check fails with CRT's wcrtomb.
   */
  set_conversion_state (&state, 1);

  if (1) {
    char c = EOF;

    assert (wcrtomb (&c, L'\0', &state) == (size_t) -1);
    assert (c == EOF);
    assert (errno == EINVAL);
    assert (!mbsinit (&state));

    // reset errno
    _set_errno (0);
  }

  /**
   * Set conversion state to initial state
   */

  assert (wcrtomb (NULL, WEOF, &state) == 1);
  assert (errno == 0);
  assert (mbsinit (&state));

  /**
   * Try convert character which cannot be repesented by a single byte
   */
  if (1) {
    char buffer = EOF;

    assert (wcrtomb (&buffer, L'語', &state) == (size_t) -1);
    assert (buffer == EOF);
    assert (errno == EILSEQ);
    assert (mbsinit (&state));

    // reset errno
    _set_errno (0);
  }

  /**
   * Try to convert low and high surrogates
   */
  for (wchar_t wc = 0;; ++wc) {
    if (IS_LOW_SURROGATE (wc) || IS_HIGH_SURROGATE (wc)) {
      char c = EOF;

      assert (wcrtomb (&c, wc, &state) == (size_t) -1);
      assert (c == EOF);
      assert (errno = EILSEQ);
      assert (mbsinit (&state));

      // reset errno
      _set_errno (0);
    }

    if (wc == WEOF) {
      break;
    }
  }

  /**
   * Test SBCS code page
   * NOTE: Code page 28951 is ISO-8859-1
   */
  assert (setlocale (LC_ALL, "English_United States.28591") != NULL);
  assert (MB_CUR_MAX == 1);

  /**
   * All values in range [0,255] must convert to themselves
   */
  for (wchar_t wc = 0; wc < 0x100; ++wc) {
    char c = EOF;

    assert (wcrtomb (&c, wc, &state) == 1);
    assert ((unsigned char) c == wc);
    assert (errno == 0);
    assert (mbsinit (&state));
  }

  /**
   * Try to convert low and high surrogates
   */
  for (wchar_t wc = 0;; ++wc) {
    if (IS_LOW_SURROGATE (wc) || IS_HIGH_SURROGATE (wc)) {
      char c = EOF;

      assert (wcrtomb (&c, wc, &state) == (size_t) -1);
      /* This assertion fails with CRT's version */
      assert (c == EOF);
      assert (errno = EILSEQ);
      assert (mbsinit (&state));

      // reset errno
      _set_errno (0);
    }

    if (wc == WEOF) {
      break;
    }
  }

  /**
   * Test DBCS code page
   */
  assert (setlocale (LC_ALL, "Japanese_Japan.932") != NULL);
  assert (MB_CUR_MAX == 2);

  /**
   * All values in range [0,127] are valid ASCII characters
   */
  for (wchar_t wc = 0; wc < 0x80; ++wc) {
    char c = EOF;

    assert (wcrtomb (&c, wc, &state) == 1);
    assert ((unsigned char) c == wc);
    assert (errno == 0);
    assert (mbsinit (&state));
  }

  /**
   * Try convert multibyte characters
   */
  wchar_t DBCS[] = {L'日', L'本', L'語', L'。'};

  for (size_t i = 0; i < _countof (DBCS); ++i) {
    char buffer[2] = {0};

    assert (wcrtomb (buffer, DBCS[i], &state) == 2);
    assert (buffer[0] != 0 && buffer[1] != 0);
    assert (errno == 0);
    assert (mbsinit (&state));
  }

  /**
   * Try to convert low and high surrogates
   */
  for (wchar_t wc = 0;; ++wc) {
    if (IS_LOW_SURROGATE (wc) || IS_HIGH_SURROGATE (wc)) {
      char c = EOF;

      assert (wcrtomb (&c, wc, &state) == (size_t) -1);
      /* This assertion fails with CRT's version */
      assert (c == EOF);
      assert (errno = EILSEQ);
      assert (mbsinit (&state));

      // reset errno
      _set_errno (0);
    }

    if (wc == WEOF) {
      break;
    }
  }

  return 0;
}
