// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <fuchsia/intl/cpp/fidl.h>
#include <fuchsia/settings/cpp/fidl.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/sys/cpp/service_directory.h>
#include <lib/sys/cpp/testing/test_with_environment_fixture.h>
#include <lib/zx/time.h>
#include <zircon/status.h>

using fuchsia::intl::LocaleId;
using fuchsia::intl::Profile;
using fuchsia::intl::TemperatureUnit;
using fuchsia::intl::TimeZoneId;
using fuchsia::settings::Error;
using fuchsia::settings::HourCycle;
using fuchsia::settings::IntlSettings;

static const int32_t kTimeoutSec = 30;

// See README.md for more detail about this test.
class IntlServicesTest : public gtest::TestWithEnvironmentFixture {
 public:
  IntlServicesTest()
      : deadline_(zx::clock::get_monotonic() + zx::sec(kTimeoutSec)),
        ctx_(sys::ComponentContext::CreateAndServeOutgoingDirectory()),
        settings_intl_(ctx_->svc()->Connect<fuchsia::settings::Intl>()),
        intl_property_provider_(ctx_->svc()->Connect<fuchsia::intl::PropertyProvider>()),
        settings_intl_status_(ZX_OK),
        intl_property_provider_status_(ZX_OK) {
    settings_intl_.set_error_handler(
        [this](zx_status_t status) { settings_intl_status_ = status; });
    intl_property_provider_.set_error_handler(
        [this](zx_status_t status) { intl_property_provider_status_ = status; });
  }

  // Returns true if any error occurred in the FIDL roundtrip.
  bool FIDLError() const {
    return intl_property_provider_status_ != ZX_OK || settings_intl_status_ != ZX_OK;
  }

  // Returns true if timeout occurred.  Used so that the tests do not block.
  bool Timeout() const {
    zx::time now = zx::clock::get_monotonic();
    return now > deadline_;
  }

 protected:
  zx::time deadline_;

  std::unique_ptr<sys::ComponentContext> ctx_;
  fuchsia::settings::IntlPtr settings_intl_;
  fuchsia::intl::PropertyProviderPtr intl_property_provider_;

  zx_status_t settings_intl_status_;
  zx_status_t intl_property_provider_status_;
};

TEST_F(IntlServicesTest, AsyncSetThenGet) {
  // Run a dummy GetProfile first, to ensure the event loop is ran until the
  // binding from this test's client is registered with the server.  This avoids
  // a data race between the binding and the notification that may happen below.
  // if the first OnChange event is sent out to the server before a binding
  // exists, causing this test to miss the OnChange notification.
  bool dummy_get_completed{};
  auto dummy_get_callback = [&](fuchsia::intl::Profile res) { dummy_get_completed = true; };
  intl_property_provider_->GetProfile(dummy_get_callback);
  RunLoopUntil([&] { return dummy_get_completed || FIDLError() || Timeout(); });
  ASSERT_FALSE(FIDLError());
  ASSERT_FALSE(Timeout());

  Profile get_result;
  bool get_completed{};
  auto get_callback = [&](fuchsia::intl::Profile res) {
    get_result = std::move(res);
    get_completed = true;
  };

  bool on_change_completed{};
  intl_property_provider_.events().OnChange = [&] {
    // Reading the profile before OnChange arrives will cause a data race and
    // make result comparison flaky in the test.
    intl_property_provider_->GetProfile(get_callback);
    on_change_completed = true;
  };

  fpromise::result<void, Error> set_result;
  bool set_completed{};
  auto set_callback = [&](fpromise::result<void, Error> res) {
    set_result = std::move(res);
    set_completed = true;
  };

  IntlSettings settings;
  settings.set_locales({LocaleId{.id = "ru-RU"}});
  settings.set_time_zone_id(TimeZoneId{.id = "Europe/Moscow"});
  settings.set_temperature_unit(TemperatureUnit::CELSIUS);
  settings.set_hour_cycle(HourCycle::H23);

  settings_intl_->Set(std::move(settings), set_callback);
  RunLoopUntil([&] {
    return (set_completed && get_completed && on_change_completed) || FIDLError() || Timeout();
  });

  ASSERT_EQ(ZX_OK, settings_intl_status_) << zx_status_get_string(settings_intl_status_);
  ASSERT_EQ(ZX_OK, intl_property_provider_status_)
      << zx_status_get_string(intl_property_provider_status_);

  // The test should normally run for a fraction of a second, so even though this measures time
  // *after* the test events completed, it should not matter for timeout checks.
  ASSERT_FALSE(Timeout()) << "Test took too long to complete: "
                          << " set_completed=" << set_completed
                          << " get_completed=" << get_completed
                          << " on_change_completed=" << on_change_completed;

  ASSERT_TRUE(set_result.is_ok());

  EXPECT_EQ(TemperatureUnit::CELSIUS, get_result.temperature_unit());
  EXPECT_EQ("Europe/Moscow", get_result.time_zones()[0].id);
  EXPECT_EQ("ru-RU-u-ca-gregory-fw-mon-hc-h23-ms-metric-nu-latn-tz-rumow",
            get_result.locales()[0].id)
      << "Expected BCP-47 locale";
}
