#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;
    }
  }

  /**
   * Disable tests for DBCS code pages with msvcrt10.dll since it does not
   * support multibyte characters.
   *
   * Calling setlocale with locale string which requests DBCS code page
   * result in runtime error.
   */
#if __MSVCRT_VERSION__ != 0x0100
  /**
   * 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;
    }
  }
#endif
  return 0;
}
