/*
 * Copyright (C) 2019 Igalia S.L.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 */

#include "config.h"
#include "JSCOptions.h"

#include "Options.h"
#include <glib/gi18n-lib.h>
#include <wtf/Vector.h>
#include <wtf/glib/GUniquePtr.h>

/**
 * SECTION: JSCOptions
 * @short_description: JavaScript options
 * @title: JSCOptions
 *
 * JavaScript options allow changing the behavior of the JavaScript engine.
 * They affect the way the engine works, so it's encouraged to set the options
 * at the very beginning of the program execution, before any other JavaScript
 * API call. Most of the options are only useful for testing and debugging.
 * Only a few of them are documented; you can use the undocumented options at
 * your own risk. (You can find the list of options in the WebKit source code).
 *
 * The API allows to set and get any option using the types defined in #JSCOptionType.
 * You can also iterate all the available options using jsc_options_foreach() and
 * passing a #JSCOptionsFunc callback. If your application uses #GOptionContext to handle
 * command line arguments, you can easily integrate the JSCOptions by adding the
 * #GOptionGroup returned by jsc_options_get_option_group().
 *
 * Since: 2.24
 */

using namespace JSC;

using int32 = int32_t;
using size = size_t;

static bool valueFromGValue(const GValue* gValue, bool& value)
{
    value = g_value_get_boolean(gValue);
    return true;
}

static void valueToGValue(bool value, GValue* gValue)
{
    g_value_set_boolean(gValue, value);
}

static bool valueFromGValue(const GValue* gValue, int32_t& value)
{
    value = g_value_get_int(gValue);
    return true;
}

static void valueToGValue(int32_t value, GValue* gValue)
{
    g_value_set_int(gValue, value);
}

#if CPU(ADDRESS64)
static bool valueFromGValue(const GValue* gValue, unsigned& value)
{
    value = g_value_get_uint(gValue);
    return true;
}

static void valueToGValue(unsigned value, GValue* gValue)
{
    g_value_set_uint(gValue, value);
}
#endif

static bool valueFromGValue(const GValue* gValue, size_t& value)
{
    value = GPOINTER_TO_SIZE(g_value_get_pointer(gValue));
    return true;
}

static void valueToGValue(size_t value, GValue* gValue)
{
    g_value_set_pointer(gValue, GSIZE_TO_POINTER(value));
}

static bool valueFromGValue(const GValue* gValue, const char*& value)
{
    value = g_value_dup_string(gValue);
    return true;
}

static void valueToGValue(const char* value, GValue* gValue)
{
    g_value_set_string(gValue, value);
}

static bool valueFromGValue(const GValue* gValue, double& value)
{
    value = g_value_get_double(gValue);
    return true;
}

static void valueToGValue(double value, GValue* gValue)
{
    g_value_set_double(gValue, value);
}

static bool valueFromGValue(const GValue* gValue, OptionRange& value)
{
    return value.init(g_value_get_string(gValue) ? g_value_get_string(gValue) : "<null>");
}

static void valueToGValue(const OptionRange& value, GValue* gValue)
{
    const char* rangeString = value.rangeString();
    g_value_set_string(gValue, !g_strcmp0(rangeString, "<null>") ? nullptr : rangeString);
}

static bool valueFromGValue(const GValue* gValue, GCLogging::Level& value)
{
    switch (g_value_get_uint(gValue)) {
    case 0:
        value = GCLogging::Level::None;
        return true;
    case 1:
        value = GCLogging::Level::Basic;
        return true;
    case 2:
        value = GCLogging::Level::Verbose;
        return true;
    default:
        break;
    }

    return false;
}

static void valueToGValue(GCLogging::Level value, GValue* gValue)
{
    switch (value) {
    case GCLogging::Level::None:
        g_value_set_uint(gValue, 0);
        break;
    case GCLogging::Level::Basic:
        g_value_set_uint(gValue, 1);
        break;
    case GCLogging::Level::Verbose:
        g_value_set_uint(gValue, 2);
        break;
    }
}

static gboolean jscOptionsSetValue(const char* option, const GValue* value)
{
#define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \
    if (!g_strcmp0(#name_, option)) {                                   \
        type_ valueToSet;                                               \
        if (!valueFromGValue(value, valueToSet))                        \
            return FALSE;                                               \
        Options::name_() = valueToSet;                                  \
        return TRUE;                                                    \
    }

    Options::initialize();
    JSC_OPTIONS(FOR_EACH_OPTION)
#undef FOR_EACH_OPTION

    return FALSE;
}

static gboolean jscOptionsGetValue(const char* option, GValue* value)
{
#define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \
    if (!g_strcmp0(#name_, option)) {                                   \
        type_ valueToGet = Options::name_();                            \
        valueToGValue(valueToGet, value);                               \
        return TRUE;                                                    \
    }

    Options::initialize();
    JSC_OPTIONS(FOR_EACH_OPTION)
#undef FOR_EACH_OPTION

    return FALSE;
}

/**
 * jsc_options_set_boolean:
 * @option: the option identifier
 * @value: the value to set
 *
 * Set @option as a #gboolean value.
 *
 * Returns: %TRUE if option was correctly set or %FALSE otherwise.
 *
 * Since: 2.24
 */
gboolean jsc_options_set_boolean(const char* option, gboolean value)
{
    g_return_val_if_fail(option, FALSE);

    GValue gValue = G_VALUE_INIT;
    g_value_init(&gValue, G_TYPE_BOOLEAN);
    g_value_set_boolean(&gValue, value);
    return jscOptionsSetValue(option, &gValue);
}

/**
 * jsc_options_get_boolean:
 * @option: the option identifier
 * @value: (out): return location for the option value
 *
 * Get @option as a #gboolean value.
 *
 * Returns: %TRUE if @value has been set or %FALSE if the option doesn't exist
 *
 * Since: 2.24
 */
gboolean jsc_options_get_boolean(const char* option, gboolean* value)
{
    g_return_val_if_fail(option, FALSE);
    g_return_val_if_fail(value, FALSE);

    GValue gValue = G_VALUE_INIT;
    g_value_init(&gValue, G_TYPE_BOOLEAN);
    if (!jscOptionsGetValue(option, &gValue))
        return FALSE;

    *value =  g_value_get_boolean(&gValue);
    return TRUE;
}

/**
 * jsc_options_set_int:
 * @option: the option identifier
 * @value: the value to set
 *
 * Set @option as a #gint value.
 *
 * Returns: %TRUE if option was correctly set or %FALSE otherwise.
 *
 * Since: 2.24
 */
gboolean jsc_options_set_int(const char* option, gint value)
{
    g_return_val_if_fail(option, FALSE);

    GValue gValue = G_VALUE_INIT;
    g_value_init(&gValue, G_TYPE_INT);
    g_value_set_int(&gValue, value);
    return jscOptionsSetValue(option, &gValue);
}

/**
 * jsc_options_get_int:
 * @option: the option identifier
 * @value: (out): return location for the option value
 *
 * Get @option as a #gint value.
 *
 * Returns: %TRUE if @value has been set or %FALSE if the option doesn't exist
 *
 * Since: 2.24
 */
gboolean jsc_options_get_int(const char* option, gint* value)
{
    g_return_val_if_fail(option, FALSE);
    g_return_val_if_fail(value, FALSE);

    GValue gValue = G_VALUE_INIT;
    g_value_init(&gValue, G_TYPE_INT);
    if (!jscOptionsGetValue(option, &gValue))
        return FALSE;

    *value = g_value_get_int(&gValue);
    return TRUE;
}

/**
 * jsc_options_set_uint:
 * @option: the option identifier
 * @value: the value to set
 *
 * Set @option as a #guint value.
 *
 * Returns: %TRUE if option was correctly set or %FALSE otherwise.
 *
 * Since: 2.24
 */
gboolean jsc_options_set_uint(const char* option, guint value)
{
    g_return_val_if_fail(option, FALSE);

    GValue gValue = G_VALUE_INIT;
    g_value_init(&gValue, G_TYPE_UINT);
    g_value_set_uint(&gValue, value);
    return jscOptionsSetValue(option, &gValue);
}

/**
 * jsc_options_get_uint:
 * @option: the option identifier
 * @value: (out): return location for the option value
 *
 * Get @option as a #guint value.
 *
 * Returns: %TRUE if @value has been set or %FALSE if the option doesn't exist
 *
 * Since: 2.24
 */
gboolean jsc_options_get_uint(const char* option, guint* value)
{
    g_return_val_if_fail(option, FALSE);
    g_return_val_if_fail(value, FALSE);

    GValue gValue = G_VALUE_INIT;
    g_value_init(&gValue, G_TYPE_UINT);
    if (!jscOptionsGetValue(option, &gValue))
        return FALSE;

    *value = g_value_get_uint(&gValue);
    return TRUE;
}

/**
 * jsc_options_set_size:
 * @option: the option identifier
 * @value: the value to set
 *
 * Set @option as a #gsize value.
 *
 * Returns: %TRUE if option was correctly set or %FALSE otherwise.
 *
 * Since: 2.24
 */
gboolean jsc_options_set_size(const char* option, gsize value)
{
    g_return_val_if_fail(option, FALSE);

    GValue gValue = G_VALUE_INIT;
    g_value_init(&gValue, G_TYPE_POINTER);
    g_value_set_pointer(&gValue, GSIZE_TO_POINTER(value));
    return jscOptionsSetValue(option, &gValue);
}

/**
 * jsc_options_get_size:
 * @option: the option identifier
 * @value: (out): return location for the option value
 *
 * Get @option as a #gsize value.
 *
 * Returns: %TRUE if @value has been set or %FALSE if the option doesn't exist
 *
 * Since: 2.24
 */
gboolean jsc_options_get_size(const char* option, gsize* value)
{
    g_return_val_if_fail(option, FALSE);
    g_return_val_if_fail(value, FALSE);

    GValue gValue = G_VALUE_INIT;
    g_value_init(&gValue, G_TYPE_POINTER);
    if (!jscOptionsGetValue(option, &gValue))
        return FALSE;

    *value = GPOINTER_TO_SIZE(g_value_get_pointer(&gValue));
    return TRUE;
}

/**
 * jsc_options_set_double:
 * @option: the option identifier
 * @value: the value to set
 *
 * Set @option as a #gdouble value.
 *
 * Returns: %TRUE if option was correctly set or %FALSE otherwise.
 *
 * Since: 2.24
 */
gboolean jsc_options_set_double(const char* option, gdouble value)
{
    g_return_val_if_fail(option, FALSE);

    GValue gValue = G_VALUE_INIT;
    g_value_init(&gValue, G_TYPE_DOUBLE);
    g_value_set_double(&gValue, value);
    return jscOptionsSetValue(option, &gValue);
}

/**
 * jsc_options_get_double:
 * @option: the option identifier
 * @value: (out): return location for the option value
 *
 * Get @option as a #gdouble value.
 *
 * Returns: %TRUE if @value has been set or %FALSE if the option doesn't exist
 *
 * Since: 2.24
 */
gboolean jsc_options_get_double(const char* option, gdouble* value)
{
    g_return_val_if_fail(option, FALSE);
    g_return_val_if_fail(value, FALSE);

    GValue gValue = G_VALUE_INIT;
    g_value_init(&gValue, G_TYPE_DOUBLE);
    if (!jscOptionsGetValue(option, &gValue))
        return FALSE;

    *value = g_value_get_double(&gValue);
    return TRUE;
}

/**
 * jsc_options_set_string:
 * @option: the option identifier
 * @value: the value to set
 *
 * Set @option as a string.
 *
 * Returns: %TRUE if option was correctly set or %FALSE otherwise.
 *
 * Since: 2.24
 */
gboolean jsc_options_set_string(const char* option, const char* value)
{
    g_return_val_if_fail(option, FALSE);

    GValue gValue = G_VALUE_INIT;
    g_value_init(&gValue, G_TYPE_STRING);
    g_value_set_string(&gValue, value);
    bool success = jscOptionsSetValue(option, &gValue);
    g_value_unset(&gValue);
    return success;
}

/**
 * jsc_options_get_string:
 * @option: the option identifier
 * @value: (out): return location for the option value
 *
 * Get @option as a string.
 *
 * Returns: %TRUE if @value has been set or %FALSE if the option doesn't exist
 *
 * Since: 2.24
 */
gboolean jsc_options_get_string(const char* option, char** value)
{
    g_return_val_if_fail(option, FALSE);
    g_return_val_if_fail(value, FALSE);

    GValue gValue = G_VALUE_INIT;
    g_value_init(&gValue, G_TYPE_STRING);
    if (!jscOptionsGetValue(option, &gValue))
        return FALSE;

    *value = g_value_dup_string(&gValue);
    g_value_unset(&gValue);
    return TRUE;
}

/**
 * jsc_options_set_range_string:
 * @option: the option identifier
 * @value: the value to set
 *
 * Set @option as a range string. The string must be in the
 * format <emphasis>[!]&lt;low&gt;[:&lt;high&gt;]</emphasis> where low and high are #guint values.
 * Values between low and high (both included) will be considered in
 * the range, unless <emphasis>!</emphasis> is used to invert the range.
 *
 * Returns: %TRUE if option was correctly set or %FALSE otherwise.
 *
 * Since: 2.24
 */
gboolean jsc_options_set_range_string(const char* option, const char* value)
{
    g_return_val_if_fail(option, FALSE);

    GValue gValue = G_VALUE_INIT;
    g_value_init(&gValue, G_TYPE_STRING);
    g_value_set_string(&gValue, value);
    bool success = jscOptionsSetValue(option, &gValue);
    g_value_unset(&gValue);
    return success;
}

/**
 * jsc_options_get_range_string:
 * @option: the option identifier
 * @value: (out): return location for the option value
 *
 * Get @option as a range string. The string must be in the
 * format <emphasis>[!]&lt;low&gt;[:&lt;high&gt;]</emphasis> where low and high are #guint values.
 * Values between low and high (both included) will be considered in
 * the range, unless <emphasis>!</emphasis> is used to invert the range.
 *
 * Returns: %TRUE if @value has been set or %FALSE if the option doesn't exist
 *
 * Since: 2.24
 */
gboolean jsc_options_get_range_string(const char* option, char** value)
{
    g_return_val_if_fail(option, FALSE);
    g_return_val_if_fail(value, FALSE);

    GValue gValue = G_VALUE_INIT;
    g_value_init(&gValue, G_TYPE_STRING);
    if (!jscOptionsGetValue(option, &gValue))
        return FALSE;

    *value = g_value_dup_string(&gValue);
    g_value_unset(&gValue);
    return TRUE;
}

static JSCOptionType jscOptionsType(bool)
{
    return JSC_OPTION_BOOLEAN;
}

static JSCOptionType jscOptionsType(int)
{
    return JSC_OPTION_INT;
}

#if CPU(ADDRESS64)
static JSCOptionType jscOptionsType(unsigned)
{
    return JSC_OPTION_UINT;
}
#endif

static JSCOptionType jscOptionsType(size_t)
{
    return JSC_OPTION_SIZE;
}

static JSCOptionType jscOptionsType(double)
{
    return JSC_OPTION_DOUBLE;
}

static JSCOptionType jscOptionsType(const char*)
{
    return JSC_OPTION_STRING;
}

static JSCOptionType jscOptionsType(const OptionRange&)
{
    return JSC_OPTION_RANGE_STRING;
}

/**
 * JSCOptionType:
 * @JSC_OPTION_BOOLEAN: A #gboolean option type.
 * @JSC_OPTION_INT: A #gint option type.
 * @JSC_OPTION_UINT: A #guint option type.
 * @JSC_OPTION_SIZE: A #gsize options type.
 * @JSC_OPTION_DOUBLE: A #gdouble options type.
 * @JSC_OPTION_STRING: A string option type.
 * @JSC_OPTION_RANGE_STRING: A range string option type.
 *
 * Enum values for options types.
 *
 * Since: 2.24
 */

/**
 * JSCOptionsFunc:
 * @option: the option name
 * @type: the option #JSCOptionType
 * @description: (nullable): the option description, or %NULL
 * @user_data: user data
 *
 * Function used to iterate options.
 *
 * Not that @description string is not localized.
 *
 * Returns: %TRUE to stop the iteration, or %FALSE otherwise
 *
 * Since: 2.24
 */

/**
 * jsc_options_foreach:
 * @function: (scope call): a #JSCOptionsFunc callback
 * @user_data: callback user data
 *
 * Iterates all available options calling @function for each one. Iteration can
 * stop early if @function returns %FALSE.
 *
 * Since: 2.24
 */
void jsc_options_foreach(JSCOptionsFunc function, gpointer userData)
{
    g_return_if_fail(function);

#define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \
    if (Options::Availability::availability_ == Options::Availability::Normal \
        || Options::isAvailable(Options::name_##ID, Options::Availability::availability_)) { \
        type_ defaultValue { };                                         \
        auto optionType = jscOptionsType(defaultValue);                 \
        if (function (#name_, optionType, description_, userData))      \
            return;                                                     \
    }

    Options::initialize();
    JSC_OPTIONS(FOR_EACH_OPTION)
#undef FOR_EACH_OPTION
}

static gboolean setOptionEntry(const char* optionNameFull, const char* value, gpointer, GError** error)
{
    const char* optionName = optionNameFull + 6; // Remove the --jsc- prefix.
    GUniquePtr<char> option(g_strdup_printf("%s=%s", optionName, value));
    if (!Options::setOption(option.get())) {
        g_set_error(error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE, "Failed parse value '%s' for %s", value, optionNameFull);
        return FALSE;
    }
    return TRUE;
}

/**
 * jsc_options_get_option_group:
 *
 * Create a #GOptionGroup to handle JSCOptions as command line arguments.
 * The options will be exposed as command line arguments with the form
 * <emphasis>--jsc-&lt;option&gt;=&lt;value&gt;</emphasis>.
 * Each entry in the returned #GOptionGroup is configured to apply the
 * corresponding option during command line parsing. Applications only need to
 * pass the returned group to g_option_context_add_group(), and the rest will
 * be taken care for automatically.
 *
 * Returns: (transfer full): a #GOptionGroup for the JSCOptions
 *
 * Since: 2.24
 */
GOptionGroup* jsc_options_get_option_group(void)
{
    // GOptionEntry works with const strings, so we need to keep the option names around.
    auto* names = new Vector<GUniquePtr<char>>;
    GOptionGroup* group = g_option_group_new("jsc", _("JSC Options"), _("Show JSC Options"), names, [] (gpointer data) {
        delete static_cast<Vector<GUniquePtr<char>>*>(data);
    });
    g_option_group_set_translation_domain(group, GETTEXT_PACKAGE);

    GArray* entries = g_array_new(TRUE, TRUE, sizeof(GOptionEntry));
#define FOR_EACH_OPTION(type_, name_, defaultValue_, availability_, description_) \
    if (Options::Availability::availability_ == Options::Availability::Normal \
        || Options::isAvailable(Options::name_##ID, Options::Availability::availability_)) { \
        GUniquePtr<char> name(g_strdup_printf("jsc-%s", #name_));       \
        entries = g_array_set_size(entries, entries->len + 1); \
        GOptionEntry* entry = &g_array_index(entries, GOptionEntry, entries->len - 1); \
        entry->long_name = name.get();                                  \
        entry->arg = G_OPTION_ARG_CALLBACK;                             \
        entry->arg_data = reinterpret_cast<gpointer>(setOptionEntry);   \
        entry->description = description_;                              \
        names->append(WTFMove(name));                                   \
    }

    Options::initialize();
    JSC_OPTIONS(FOR_EACH_OPTION)
#undef FOR_EACH_OPTION

    g_option_group_add_entries(group, reinterpret_cast<GOptionEntry*>(entries->data));
    return group;
}

/**
 * JSC_OPTIONS_USE_JIT:
 *
 * Allows the executable pages to be allocated for JIT and thunks if %TRUE.
 * Option type: %JSC_OPTION_BOOLEAN
 * Default value: %TRUE.
 *
 * Since: 2.24
 */

/**
 * JSC_OPTIONS_USE_DFG:
 *
 * Allows the DFG JIT to be used if %TRUE.
 * Option type: %JSC_OPTION_BOOLEAN
 * Default value: %TRUE.
 *
 * Since: 2.24
 */

/**
 * JSC_OPTIONS_USE_FTL:
 *
 * Allows the FTL JIT to be used if %TRUE.
 * Option type: %JSC_OPTION_BOOLEAN
 * Default value: %TRUE.
 *
 * Since: 2.24
 */

/**
 * JSC_OPTIONS_USE_LLINT:
 *
 * Allows the LLINT to be used if %TRUE.
 * Option type: %JSC_OPTION_BOOLEAN
 * Default value: %TRUE.
 *
 * Since: 2.24
 */
