/*
 * Copyright 2025 Rive
 */

#if defined(__EMSCRIPTEN__)

#include "common/rive_wasm_app.hpp"

#include "common/test_harness.hpp"
#include <emscripten/emscripten.h>
#include <emscripten/html5.h>
#include <sstream>
#include <vector>

EM_JS(char*, get_window_location, (), {
  var jsString = window.location.href;
  var lengthBytes = lengthBytesUTF8(jsString) + 1;
  var stringOnWasmHeap = _malloc(lengthBytes);
  stringToUTF8(jsString, stringOnWasmHeap, lengthBytes);
  return stringOnWasmHeap;
});

EM_JS(char*, get_window_location_hash, (), {
  var jsString = window.location.hash.substring(1);
  var lengthBytes = lengthBytesUTF8(jsString) + 1;
  var stringOnWasmHeap = _malloc(lengthBytes);
  stringToUTF8(jsString, stringOnWasmHeap, lengthBytes);
  return stringOnWasmHeap;
});

static void split_string(
    const std::string& str,
    const std::string& delimiter,
    std::vector<std::string>& result)
{
  size_t start = 0;
  size_t end;

  while ((end = str.find(delimiter, start)) != std::string::npos)
  {
    if (end > start)
    {
      result.push_back(str.substr(start, end - start));
    }
    start = end + delimiter.length();
  }

  if (str.length() > start)
  {
    // Add the last piece
    result.push_back(str.substr(start));
  }
}

int main()
{
  char* location = get_window_location();
  char* hash = get_window_location_hash();

  // Command line arguments are passed via the window location's hash string.
  //
  //   e.g., "http://localhost/my_app.html#--backend%20gl%20--another%20arg"
  //
  std::vector<std::string> hashStrs = {location};
  split_string(hash, "%20", hashStrs);

  free(hash);
  free(location);

  std::vector<const char*> hashArgs;
  for (const std::string& str : hashStrs)
  {
    hashArgs.push_back(str.c_str());
  }

  return rive_wasm_main(hashArgs.size(), hashArgs.data());
}

extern "C" void rive_print_message_on_server(const char* msg)
{
  // stdout and stderr get redirected here and forwarded to the server for
  // logging.
  static bool nested = false;
  if (nested)
  {
    // Avoid accidental infinite recursion in case anything gets printed
    // inside printMessageOnServer().
    // These messages will still make it to the browser's console.
    return;
  }
  nested = true;
  TestHarness::Instance().printMessageOnServer(msg);
  nested = false;
}

#endif
