#ifdef NDEBUG
#undef NDEBUG
#endif

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

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

char Ascii[] = {'a'};
char NonAscii[] = {(char) 0x80};
char Multibyte[] = {(char) 0x81, (char) 0x81};
char InvalidMultibyte[] = {(char) 0x81, 0};

int main (void) {
#if __MSVCRT_VERSION__ >= 0x0800
  return 77;
#endif
  mbstate_t state = {0};
  wchar_t   wc = WEOF;

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

  /**
   * All bytes in range [0,255] are valid and must convert to themselves
   */
  for (unsigned char c = 0;; ++c) {
    assert (mbrtowc (&wc, (char *) &c, MB_CUR_MAX, &state) == !!c);
    assert (wc == c);
    assert (mbsinit (&state));
    assert (errno == 0);

    if (c == 0xFF) {
      break;
    }
  }

  /**
   * Detect invalid conversion state
   *
   * NOTE: this is optional error condition specified in POSIX.
   * This check fails with CRT's mbrtowc.
   */
  set_conversion_state (&state, Ascii[0]);
  wc = WEOF;

  assert (mbrtowc (&wc, (char *) &Ascii, MB_CUR_MAX, &state) == (size_t) -1);
  assert (wc == WEOF);
  assert (!mbsinit (&state));
  assert (errno == EINVAL);

  // reset errno
  _set_errno (0);

  /**
   * Set conversion state to initial state
   */
  wc = WEOF;

  assert (mbrtowc (&wc, NULL, 0, &state) == 0);
  assert (wc == WEOF);
  assert (mbsinit (&state));
  assert (errno == 0);

  /**
   * 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 bytes must be valid
   *
   * We test ISO-8859-1 so that all bytes must convert to themselves
   */
  for (unsigned char c = 0;; ++c) {
    wc = WEOF;

    assert (mbrtowc (&wc, (char *) &c, MB_CUR_MAX, &state) == !!c);
    assert (wc == c);
    assert (mbsinit (&state));
    assert (errno == 0);

    if (c == 0xFF) {
      break;
    }
  }

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

  /**
   * Make sure ASCII characters are handled correctly
   */
  for (char c = 0;; ++c) {
    wc = WEOF;

    assert (mbrtowc (&wc, &c, 1, &state) == !!c);
    assert (wc == c);
    assert (mbsinit (&state));
    assert (errno == 0);

    if (c == 0x7F) {
      break;
    }
  }

  /**
   * Try convert incomplete multibyte character
   */
  wc = WEOF;

  assert (mbrtowc (&wc, (char *) Multibyte, 1, &state) == (size_t) -2);
  /* This assertion fails with CRT's version */
  assert (wc == WEOF);
  assert (!mbsinit (&state));
  assert (errno == 0);

  /**
   * Complete multibyte character
   *
   * NOTE: return value does not conform to ISO C and POSIX.
   * This behavior is implemented for consistency with CRT.
   */
  wc = WEOF;

  assert (mbrtowc (&wc, (char *) Multibyte + 1, 1, &state) == 2);
  assert (wc != WEOF);
  assert (mbsinit (&state));
  assert (errno == 0);

  /**
   * Convert complete multibyte character
   */
  wc = WEOF;

  assert (mbrtowc (&wc, (char *) Multibyte, MB_CUR_MAX, &state) == 2);
  assert (wc != WEOF);
  assert (mbsinit (&state));
  assert (errno == 0);

  /**
   * Try convert invalid multibyte character
   */
  wc = WEOF;

  assert (mbrtowc (&wc, (char *) InvalidMultibyte, MB_CUR_MAX, &state) == (size_t) -1);
  /* This assertion fails with CRT's version */
  assert (wc == WEOF);
  assert (mbsinit (&state));
  assert (errno == EILSEQ);

  return 0;
}
