/*
* <%= @warning %>
*
* Copyright (C) 2018 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in the
*    documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "config.h"
#include "WebPreferences.h"

#include "WebPreferencesKeys.h"

namespace WebKit {

<%- for @pref in @internalDebugFeatures do -%>
void WebPreferences::set<%= @pref.name %>(const bool& value)
{
    if (!m_store.setBoolValueForKey(WebPreferencesKey::<%= @pref.nameLower %>Key(), value))
        return;
    updateBoolValueForInternalDebugFeatureKey(WebPreferencesKey::<%= @pref.nameLower %>Key(), value);
}

bool WebPreferences::<%= @pref.nameLower %>() const
{
    return m_store.getBoolValueForKey(WebPreferencesKey::<%= @pref.nameLower %>Key());
}

<%- end -%>
const Vector<RefPtr<API::Object>>& WebPreferences::internalDebugFeatures()
{
    static NeverDestroyed<Vector<RefPtr<API::Object>>> features(std::initializer_list<RefPtr<API::Object>> {
<%- for @pref in @internalDebugFeatures do -%>
<%- if @pref.condition -%>
#if <%= @pref.condition %>
<%- end -%>
        API::InternalDebugFeature::create(<%= @pref.humanReadableName %>, "<%= @pref.name %>", <%= @pref.humanReadableDescription %>, <%= @pref.defaultValue %>, <%= @pref.hidden %>),
<%- if @pref.condition -%>
#endif
<%- end -%>
<%- end -%>
    });

    return features;
}

bool WebPreferences::isFeatureEnabled(const API::InternalDebugFeature& feature) const
{
    struct FeatureGetterMapping {
        const char* name;
        bool (WebPreferences::*function) () const;
    };

    static FeatureGetterMapping getters[] = {
<%- for @pref in @internalDebugFeatures do -%>
<%- if @pref.condition -%>
#if <%= @pref.condition %>
<%- end -%>
        { "<%= @pref.name %>", &WebPreferences::<%= @pref.nameLower %> },
<%- if @pref.condition -%>
#endif
<%- end -%>
<%- end -%>
    };

    const String& key = feature.key();

    for (auto& getter : getters) {
        if (key == getter.name)
            return (this->*getter.function)();
    }

    return false;
}

void WebPreferences::setFeatureEnabled(const API::InternalDebugFeature& feature, bool value)
{
    setInternalDebugFeatureEnabledForKey(feature.key(), value);
}

void WebPreferences::setInternalDebugFeatureEnabledForKey(const String& key, bool value)
{
    struct FeatureSetterMapping {
        const char* name;
        void (WebPreferences::*function) (const bool&);
    };

    static FeatureSetterMapping setters[] = {
<%- for @pref in @internalDebugFeatures do -%>
<%- if @pref.condition -%>
#if <%= @pref.condition %>
<%- end -%>
        { "<%= @pref.name %>", &WebPreferences::set<%= @pref.name %> },
<%- if @pref.condition -%>
#endif
<%- end -%>
<%- end -%>
    };

    for (auto& setter : setters) {
        if (key == setter.name) {
            (this->*setter.function)(value);
            return;
        }
    }
}

void WebPreferences::resetAllInternalDebugFeatures()
{
<%- for @pref in @internalDebugFeatures do -%>
<%- if @pref.condition -%>
#if <%= @pref.condition %>
<%- end -%>
    set<%= @pref.name %>(<%= @pref.defaultValue %>);
<%- if @pref.condition -%>
#endif
<%- end -%>
<%- end -%>
}

}
