#include "Utils.h"

#include <Identity.h>

namespace sharedjsi
{

Object convertConfigResultToJSIObject(Runtime &runtime, IdentityConfigResult_t result) {
  Object obj(runtime);
  obj.setProperty(runtime, "status_code", static_cast<double>(result.status_code));
  obj.setProperty(runtime, "identity_config", cPointerToJSPointerObject(runtime, result.identity_config));
  return obj;
}

Function ditto_identity_config_make_online_playground(Runtime &runtime)
{
  return Function::createFromHostFunction(runtime,
                                          PropNameID::forAscii(runtime,
                                                               STRINGIFIED_FUNC_NAME()),
                                          0,
                                          [](Runtime &runtime,
                                             const Value &thisValue,
                                             const Value *arguments,
                                             size_t count) -> Value
                                          {
    std::string app_id_str = jsTypedArrayToCString(runtime, arguments[0]);
    std::string shared_token_str = jsTypedArrayToCString(runtime, arguments[1]);
    std::string base_url_str = jsTypedArrayToCString(runtime, arguments[2]);

    const char *app_id = app_id_str.c_str();
    const char *shared_token = shared_token_str.c_str();
    const char *base_url = base_url_str.c_str();

    IdentityConfigResult_t config_result = ::ditto_identity_config_make_online_playground(app_id, shared_token, base_url);
    return convertConfigResultToJSIObject(runtime, config_result);
  });
}

Function ditto_identity_config_make_offline_playground(Runtime &runtime)
{
  return Function::createFromHostFunction(runtime,
                                          PropNameID::forAscii(runtime,
                                                               STRINGIFIED_FUNC_NAME()),
                                          0,
                                          [](Runtime &runtime,
                                             const Value &thisValue,
                                             const Value *arguments,
                                             size_t count) -> Value
                                          {
    std::string app_id_str = jsTypedArrayToCString(runtime, arguments[0]);
    const char *app_id = app_id_str.c_str();
    uint64_t site_id = bigIntOrNumberToUint64(runtime, arguments[1]);

    IdentityConfigResult_t config_result = ::ditto_identity_config_make_offline_playground(app_id, site_id);
    return convertConfigResultToJSIObject(runtime, config_result);
  });
}

Function ditto_identity_config_make_manual_v0(Runtime &runtime)
{
  return Function::createFromHostFunction(runtime,
                                          PropNameID::forAscii(runtime,
                                                               STRINGIFIED_FUNC_NAME()),
                                          0,
                                          [](Runtime &runtime,
                                             const Value &thisValue,
                                             const Value *arguments,
                                             size_t count) -> Value
                                          {
    std::string config_cbor_b64_str = jsTypedArrayToCString(runtime, arguments[0]);
    const char *config_cbor_b64 = config_cbor_b64_str.c_str();

    IdentityConfigResult_t config_result = ::ditto_identity_config_make_manual_v0(config_cbor_b64);
    return convertConfigResultToJSIObject(runtime, config_result);
  });
}

Function ditto_identity_config_make_shared_key(Runtime &runtime)
{
  return Function::createFromHostFunction(runtime,
                                          PropNameID::forAscii(runtime,
                                                               STRINGIFIED_FUNC_NAME()),
                                          0,
                                          [](Runtime &runtime,
                                             const Value &thisValue,
                                             const Value *arguments,
                                             size_t count) -> Value
                                          {
    std::string app_id_str = jsTypedArrayToCString(runtime, arguments[0]);
    const char *app_id = app_id_str.c_str();

    std::string shared_key_str = jsTypedArrayToCString(runtime, arguments[1]);
    const char *shared_key = shared_key_str.c_str();
    uint64_t site_id = bigIntOrNumberToUint64(runtime, arguments[2]);

    IdentityConfigResult_t config_result = ::ditto_identity_config_make_shared_key(app_id, shared_key, site_id);
    return convertConfigResultToJSIObject(runtime, config_result);
  });
}

Function ditto_identity_config_make_online_with_authentication(Runtime &runtime)
{
  return Function::createFromHostFunction(runtime,
                                          PropNameID::forAscii(runtime,
                                                               STRINGIFIED_FUNC_NAME()),
                                          0,
                                          [](Runtime &runtime,
                                             const Value &thisValue,
                                             const Value *arguments,
                                             size_t count) -> Value
                                          {
    std::string app_id_str = jsTypedArrayToCString(runtime, arguments[0]);
    std::string baseURLVector = jsTypedArrayToCString(runtime, arguments[1]);

    const char *app_id = app_id_str.c_str();
    const char *base_url = baseURLVector.c_str();

    IdentityConfigResult_t config_result = ::ditto_identity_config_make_online_with_authentication(app_id, base_url);
    return convertConfigResultToJSIObject(runtime, config_result);
  });
}
}
