// { dg-options "-lstdc++exp" }
// { dg-do run { target c++26 } }
// { dg-require-namedlocale "en_US.ISO8859-1" }
// { dg-require-namedlocale "fr_FR.ISO8859-15" }

#include <text_encoding>
#include <string_view>
#include <locale.h>
#include <testsuite_hooks.h>

using namespace std::string_view_literals;

void
test_literal()
{
  const std::text_encoding lit = std::text_encoding::literal();
  VERIFY( lit.name() == std::string_view(__GNUC_EXECUTION_CHARSET_NAME) );
}

void
test_env()
{
  const std::text_encoding env = std::text_encoding::environment();

  if (env.mib() == std::text_encoding::UTF8)
    VERIFY( std::text_encoding::environment_is<std::text_encoding::UTF8>() );

  ::setlocale(LC_ALL, ISO_8859(1, en_US));
  const std::text_encoding env1 = std::text_encoding::environment();
  VERIFY( env1 == env );

  ::setlocale(LC_ALL, ISO_8859(15, fr_FR));
  const std::text_encoding env2 = std::text_encoding::environment();
  VERIFY( env2 == env );
}

void
test_every_id()
{
  for (int i = 0; i <= 2260; ++i)
  {
    std::text_encoding::id mib{i};
    switch (i)
    {
    case 0:
    case 33 ... 34:
    case 107 ... 108:
    case 120 ... 999:
    case 1022 ... 1999:
    case 2110 ... 2249:
      // These do not correspond to an enumerator of std::text_encoding::id
      // so are not valid arguments to the constructor. Without assertions
      // enabled, we map bad IDs to id::unknown as a libstdc++ extension.
#ifndef _GLIBCXX_ASSERTIONS
      {
        std::text_encoding bad{mib};
        VERIFY( bad.mib() == std::text_encoding::unknown );
        VERIFY( bad.name() == ""sv );
      }
#endif
      continue;
    }
    std::text_encoding enc{mib};
    auto aliases = enc.aliases();
    if (i == 1 || i == 2)
      VERIFY( enc.name() == ""sv );
    else
      VERIFY( enc.name() == std::string_view(aliases.front()) );
    auto begin = aliases.begin();
    auto end = aliases.end();
    VERIFY( (begin + std::ranges::distance(aliases)) == end );
#ifndef _GLIBCXX_ASSERTIONS
    // This is an error, but with assertions disabled is guaranteed safe:
    VERIFY( begin[std::ranges::distance(aliases)] == ""sv );
    // Likewise:
    VERIFY( begin[999999] == *begin );
#endif
  }
}

int main()
{
  test_literal();
  test_env();
  test_every_id();
}
