/*
 * 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 Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 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 "TestMain.h"

#include "WebViewTest.h"
#include <wtf/WallTime.h>

class GeolocationTest: public WebViewTest {
public:
    MAKE_GLIB_TEST_FIXTURE(GeolocationTest);

    struct Position {
        double timestamp { std::numeric_limits<double>::quiet_NaN() };
        double latitude { std::numeric_limits<double>::quiet_NaN() };
        double longitude { std::numeric_limits<double>::quiet_NaN() };
        double accuracy { std::numeric_limits<double>::quiet_NaN() };

        std::optional<double> altitude;
        std::optional<double> altitudeAccuracy;
        std::optional<double> heading;
        std::optional<double> speed;
    };

    static gboolean startCallback(WebKitGeolocationManager* manager, GeolocationTest* test)
    {
        g_assert_true(test->m_manager == manager);
        test->start();
        return TRUE;
    }

    static void stopCallback(WebKitGeolocationManager* manager, GeolocationTest* test)
    {
        g_assert_true(test->m_manager == manager);
        test->stop();
    }

    static gboolean permissionRequested(WebKitWebView*, WebKitPermissionRequest* request, GeolocationTest* test)
    {
        g_assert_true(WEBKIT_IS_PERMISSION_REQUEST(request));
        test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request));

        if (WEBKIT_IS_GEOLOCATION_PERMISSION_REQUEST(request)) {
            webkit_permission_request_allow(request);
            return TRUE;
        }

        return FALSE;
    }

    GeolocationTest()
        : m_manager(webkit_web_context_get_geolocation_manager(m_webContext.get()))
    {
        g_assert_true(WEBKIT_IS_GEOLOCATION_MANAGER(m_manager));
        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_manager));
        g_signal_connect(m_manager, "start", G_CALLBACK(startCallback), this);
        g_signal_connect(m_manager, "stop", G_CALLBACK(stopCallback), this);
        g_signal_connect(m_webView.get(), "permission-request", G_CALLBACK(permissionRequested), this);
    }

    ~GeolocationTest()
    {
        if (m_checkPosition)
            webkit_geolocation_position_free(m_checkPosition);

        g_signal_handlers_disconnect_matched(m_manager, G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
        g_signal_handlers_disconnect_matched(m_webView.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
    }

    void start()
    {
        g_assert_false(m_updating);
        m_updating = true;

        if (m_errorMessage) {
            g_assert_false(m_checkPosition);
            webkit_geolocation_manager_failed(m_manager, m_errorMessage.get());
        }

        if (m_checkPosition) {
            g_assert_false(m_errorMessage.get());
            webkit_geolocation_manager_update_position(m_manager, m_checkPosition);
        }

        g_main_loop_quit(m_mainLoop);
    }

    void stop()
    {
        g_assert_true(m_updating);
        m_updating = false;
        if (m_watching)
            g_main_loop_quit(m_mainLoop);
    }

    Position lastPosition()
    {
        GUniqueOutPtr<GError> error;
        auto* jsPosition = runJavaScriptAndWaitUntilFinished("position", &error.outPtr());
        g_assert_nonnull(jsPosition);
        g_assert_no_error(error.get());

        g_assert_true(jsc_value_is_object(jsPosition));
        Position result;
        GRefPtr<JSCValue> value = adoptGRef(jsc_value_object_get_property(jsPosition, "latitude"));
        g_assert_true(jsc_value_is_number(value.get()));
        result.latitude = jsc_value_to_double(value.get());
        value = adoptGRef(jsc_value_object_get_property(jsPosition, "longitude"));
        g_assert_true(jsc_value_is_number(value.get()));
        result.longitude = jsc_value_to_double(value.get());
        value = adoptGRef(jsc_value_object_get_property(jsPosition, "accuracy"));
        g_assert_true(jsc_value_is_number(value.get()));
        result.accuracy = jsc_value_to_double(value.get());
        value = adoptGRef(jsc_value_object_get_property(jsPosition, "altitude"));
        if (!jsc_value_is_null(value.get())) {
            g_assert_true(jsc_value_is_number(value.get()));
            result.altitude = jsc_value_to_double(value.get());
        }
        value = adoptGRef(jsc_value_object_get_property(jsPosition, "altitudeAccuracy"));
        if (!jsc_value_is_null(value.get())) {
            g_assert_true(jsc_value_is_number(value.get()));
            result.altitudeAccuracy = jsc_value_to_double(value.get());
        }
        value = adoptGRef(jsc_value_object_get_property(jsPosition, "heading"));
        if (!jsc_value_is_null(value.get())) {
            g_assert_true(jsc_value_is_number(value.get()));
            result.heading = jsc_value_to_double(value.get());
        }
        value = adoptGRef(jsc_value_object_get_property(jsPosition, "speed"));
        if (!jsc_value_is_null(value.get())) {
            g_assert_true(jsc_value_is_number(value.get()));
            result.speed = jsc_value_to_double(value.get());
        }
        value = adoptGRef(jsc_value_object_get_property(jsPosition, "timestamp"));
        g_assert_true(jsc_value_is_number(value.get()));
        result.timestamp = jsc_value_to_double(value.get());
        return result;
    }

    Position checkCurrentPosition(WebKitGeolocationPosition* position, bool enableHighAccuracy = false)
    {
        g_clear_pointer(&m_checkPosition, webkit_geolocation_position_free);
        m_checkPosition = position;

        static const char getCurrentPosition[] =
            "var position = null;\n"
            "options = { enableHighAccuracy: %s }\n"
            "navigator.geolocation.getCurrentPosition(function(p) {\n"
            "  position = { };\n"
            "  position.latitude = p.coords.latitude;\n"
            "  position.longitude = p.coords.longitude;\n"
            "  position.accuracy = p.coords.accuracy;\n"
            "  position.altitude = p.coords.altitude;\n"
            "  position.altitudeAccuracy = p.coords.altitudeAccuracy;\n"
            "  position.heading = p.coords.heading;\n"
            "  position.speed = p.coords.speed;\n"
            "  position.timestamp = p.timestamp;\n"
            "}, undefined, options);";
        GUniquePtr<char> script(g_strdup_printf(getCurrentPosition, enableHighAccuracy ? "true" : "false"));
        GUniqueOutPtr<GError> error;
        runJavaScriptAndWaitUntilFinished(script.get(), &error.outPtr());
        g_assert_no_error(error.get());
        g_main_loop_run(m_mainLoop);
        g_clear_pointer(&m_checkPosition, webkit_geolocation_position_free);
        g_assert_true(webkit_geolocation_manager_get_enable_high_accuracy(m_manager) == enableHighAccuracy);

        return lastPosition();
    }

    GUniquePtr<char> checkFailedToDeterminePosition(const char* errorMessage)
    {
        m_errorMessage.reset(g_strdup(errorMessage));
        static const char getCurrentPosition[] =
            "var error;\n"
            "navigator.geolocation.getCurrentPosition(\n"
            "  function(p) { error = null; },\n"
            "  function(e) { error = e.message.toString(); }\n"
            ");";
        GUniqueOutPtr<GError> error;
        auto* value = runJavaScriptAndWaitUntilFinished(getCurrentPosition, &error.outPtr());
        g_assert_no_error(error.get());
        g_main_loop_run(m_mainLoop);
        m_errorMessage = nullptr;

        value = runJavaScriptAndWaitUntilFinished("error", &error.outPtr());
        g_assert_nonnull(value);
        g_assert_no_error(error.get());
        g_assert_true(jsc_value_is_string(value));
        return GUniquePtr<char>(jsc_value_to_string(value));
    }

    void startWatch()
    {
        g_clear_pointer(&m_checkPosition, webkit_geolocation_position_free);
        m_errorMessage = nullptr;

        m_watching = true;
        static const char watchPosition[] =
            "var position = null;\n"
            "var watchID = navigator.geolocation.watchPosition(function(p) {\n"
            "  position = { };\n"
            "  position.latitude = p.coords.latitude;\n"
            "  position.longitude = p.coords.longitude;\n"
            "  position.accuracy = p.coords.accuracy;\n"
            "  position.altitude = p.coords.altitude;\n"
            "  position.altitudeAccuracy = p.coords.altitudeAccuracy;\n"
            "  position.heading = p.coords.heading;\n"
            "  position.speed = p.coords.speed;\n"
            "  position.timestamp = p.timestamp;\n"
            "});";
        GUniqueOutPtr<GError> error;
        auto* value = runJavaScriptAndWaitUntilFinished(watchPosition, &error.outPtr());
        g_assert_nonnull(value);
        g_assert_no_error(error.get());
        g_main_loop_run(m_mainLoop);
    }

    void stopWatch()
    {
        GUniqueOutPtr<GError> error;
        runJavaScriptAndWaitUntilFinished("navigator.geolocation.clearWatch(watchID)", &error.outPtr());
        g_assert_no_error(error.get());
        g_main_loop_run(m_mainLoop);
        m_watching = false;
    }

    WebKitGeolocationManager* m_manager;
    bool m_updating { false };
    bool m_watching { false };
    WebKitGeolocationPosition* m_checkPosition { nullptr };
    GUniquePtr<char> m_errorMessage;
};

static void testGeolocationManagerCurrentPosition(GeolocationTest* test, gconstpointer)
{
    test->showInWindow();
    test->loadHtml("<html><body></body></html>", "https://foo.com/bar");
    test->waitUntilLoadFinished();

    WebKitGeolocationPosition* position = webkit_geolocation_position_new(37.1760783, -3.59033, 17);
    g_assert_false(test->m_updating);
    auto result = test->checkCurrentPosition(position);
    g_assert_false(test->m_updating);
    g_assert_cmpfloat(result.latitude, ==, 37.1760783);
    g_assert_cmpfloat(result.longitude, ==, -3.59033);
    g_assert_cmpfloat(result.accuracy, ==, 17);
    g_assert_false(result.altitude);
    g_assert_false(result.altitudeAccuracy);
    g_assert_false(result.heading);
    g_assert_false(result.speed);
    g_assert_cmpfloat(result.timestamp, >, 0);
    g_assert_cmpfloat(result.timestamp / 1000., <, WallTime::now().secondsSinceEpoch().value());

    position = webkit_geolocation_position_new(27.986065, 86.922623, 0);
    auto timestamp = WallTime::now().secondsSinceEpoch();
    webkit_geolocation_position_set_timestamp(position, timestamp.value());
    webkit_geolocation_position_set_altitude(position, 8495);
    webkit_geolocation_position_set_altitude_accuracy(position, 0);
    webkit_geolocation_position_set_heading(position, 100.55);
    webkit_geolocation_position_set_speed(position, 0.05);
    g_assert_false(test->m_updating);
    result = test->checkCurrentPosition(position, true);
    g_assert_false(test->m_updating);
    g_assert_cmpfloat(result.latitude, ==, 27.986065);
    g_assert_cmpfloat(result.longitude, ==, 86.922623);
    g_assert_cmpfloat(result.accuracy, ==, 0);
    g_assert_true(result.altitude);
    g_assert_cmpfloat(result.altitude.value(), ==, 8495);
    g_assert_true(result.altitudeAccuracy);
    g_assert_cmpfloat(result.altitudeAccuracy.value(), ==, 0);
    g_assert_true(result.heading);
    g_assert_cmpfloat(result.heading.value(), ==, 100.55);
    g_assert_true(result.speed);
    g_assert_cmpfloat(result.speed.value(), ==, 0.05);
    g_assert_cmpfloat_with_epsilon(result.timestamp / 1000., timestamp.value(), 1);

    auto errorMessage = test->checkFailedToDeterminePosition("GPS is not active");
    g_assert_cmpstr(errorMessage.get(), ==, "GPS is not active");
}

static void testGeolocationManagerWatchPosition(GeolocationTest* test, gconstpointer)
{
    test->showInWindow();
    test->loadHtml("<html><body></body></html>", "https://foo.com/bar");
    test->waitUntilLoadFinished();

    test->startWatch();
    g_assert_true(test->m_updating);

    WebKitGeolocationPosition* position = webkit_geolocation_position_new(37.1760783, -3.59033, 17);
    webkit_geolocation_manager_update_position(test->m_manager, position);
    webkit_geolocation_position_free(position);
    auto result = test->lastPosition();
    g_assert_cmpfloat(result.latitude, ==, 37.1760783);
    g_assert_cmpfloat(result.longitude, ==, -3.59033);
    g_assert_cmpfloat(result.accuracy, ==, 17);

    position = webkit_geolocation_position_new(38.1770783, -3.60033, 17);
    webkit_geolocation_manager_update_position(test->m_manager, position);
    webkit_geolocation_position_free(position);
    result = test->lastPosition();
    g_assert_cmpfloat(result.latitude, ==, 38.1770783);
    g_assert_cmpfloat(result.longitude, ==, -3.60033);
    g_assert_cmpfloat(result.accuracy, ==, 17);

    test->stopWatch();
    g_assert_false(test->m_updating);
}

void beforeAll()
{
    GeolocationTest::add("WebKitGeolocationManager", "current-position", testGeolocationManagerCurrentPosition);
    GeolocationTest::add("WebKitGeolocationManager", "watch-position", testGeolocationManagerWatchPosition);
}

void afterAll()
{
}
