// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/fuchsia/intl_profile_watcher.h"

#include <fuchsia/intl/cpp/fidl_test_base.h>
#include <lib/fidl/cpp/binding.h>
#include <memory>
#include <string>
#include <vector>

#include "base/check.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/test/mock_callback.h"
#include "base/test/task_environment.h"
#include "base/threading/sequence_bound.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {

namespace {

const char kPrimaryTimeZoneName[] = "Australia/Darwin";
const char kSecondaryTimeZoneName[] = "Africa/Djibouti";

const char kPrimaryLocaleName[] = "en-US";
const char kSecondaryLocaleName[] = "es-419";

template <typename FuchsiaStruct>
void CopyIdsToFuchsiaStruct(const std::vector<std::string>& raw_ids,
                            std::vector<FuchsiaStruct>* fuchsia_ids) {
  fuchsia_ids->clear();
  for (auto id : raw_ids) {
    FuchsiaStruct fuchsia_id;
    fuchsia_id.id = id;
    fuchsia_ids->push_back(fuchsia_id);
  }
}

fuchsia::intl::Profile CreateProfileWithTimeZones(
    const std::vector<std::string>& zone_ids) {
  fuchsia::intl::Profile profile;
  std::vector<::fuchsia::intl::TimeZoneId> time_zone_ids;
  CopyIdsToFuchsiaStruct(zone_ids, &time_zone_ids);
  profile.set_time_zones(time_zone_ids);
  return profile;
}

fuchsia::intl::Profile CreateProfileWithLocales(
    const std::vector<std::string>& locale_ids) {
  fuchsia::intl::Profile profile;
  std::vector<::fuchsia::intl::LocaleId> fuchsia_locale_ids;
  CopyIdsToFuchsiaStruct(locale_ids, &fuchsia_locale_ids);
  profile.set_locales(fuchsia_locale_ids);
  return profile;
}

// Partial fake implementation of a PropertyProvider.
class FakePropertyProvider
    : public ::fuchsia::intl::testing::PropertyProvider_TestBase {
 public:
  explicit FakePropertyProvider(
      fidl::InterfaceRequest<::fuchsia::intl::PropertyProvider>
          provider_request)
      : binding_(this) {
    binding_.Bind(std::move(provider_request));
    DCHECK(binding_.is_bound());
  }
  FakePropertyProvider(const FakePropertyProvider&) = delete;
  FakePropertyProvider& operator=(const FakePropertyProvider&) = delete;
  ~FakePropertyProvider() override = default;

  void Close() { binding_.Close(ZX_ERR_PEER_CLOSED); }
  void SetTimeZones(const std::vector<std::string>& zone_ids) {
    CopyIdsToFuchsiaStruct(zone_ids, &time_zone_ids_);
  }
  void SetLocales(const std::vector<std::string>& locale_ids) {
    CopyIdsToFuchsiaStruct(locale_ids, &fuchsia_locale_ids_);
  }
  void NotifyChange() { binding_.events().OnChange(); }

  // PropertyProvider_TestBase implementation.
  void GetProfile(
      ::fuchsia::intl::PropertyProvider::GetProfileCallback callback) override {
    fuchsia::intl::Profile profile;
    profile.set_time_zones(time_zone_ids_);
    profile.set_locales(fuchsia_locale_ids_);
    callback(std::move(profile));
  }
  void NotImplemented_(const std::string& name) override {
    ADD_FAILURE() << "Unimplemented function called: " << name;
  }

 private:
  ::fidl::Binding<::fuchsia::intl::PropertyProvider> binding_;

  std::vector<::fuchsia::intl::TimeZoneId> time_zone_ids_;
  std::vector<::fuchsia::intl::LocaleId> fuchsia_locale_ids_;
};

class FakePropertyProviderAsync {
 public:
  explicit FakePropertyProviderAsync(
      fidl::InterfaceRequest<::fuchsia::intl::PropertyProvider>
          provider_request)
      : thread_("Property Provider Thread") {
    CHECK(thread_.StartWithOptions(
        base::Thread::Options(base::MessagePumpType::IO, 0)));
    property_provider_ = base::SequenceBound<FakePropertyProvider>(
        thread_.task_runner(), std::move(provider_request));
  }
  FakePropertyProviderAsync(const FakePropertyProviderAsync&) = delete;
  FakePropertyProviderAsync& operator=(const FakePropertyProviderAsync&) =
      delete;
  ~FakePropertyProviderAsync() = default;

  void Close() { property_provider_.AsyncCall(&FakePropertyProvider::Close); }
  void SetTimeZones(const std::vector<std::string>& zone_ids) {
    property_provider_.AsyncCall(&FakePropertyProvider::SetTimeZones)
        .WithArgs(zone_ids);
  }
  void SetLocales(const std::vector<std::string>& locale_ids) {
    property_provider_.AsyncCall(&FakePropertyProvider::SetLocales)
        .WithArgs(locale_ids);
  }
  void NotifyChange() {
    property_provider_.AsyncCall(&FakePropertyProvider::NotifyChange);
  }

 private:
  base::Thread thread_;
  base::SequenceBound<FakePropertyProvider> property_provider_;
};

}  // namespace

class GetValuesFromIntlPropertyProviderTest : public testing::Test {
 public:
  GetValuesFromIntlPropertyProviderTest()
      : property_provider_(property_provider_ptr_.NewRequest()) {}
  GetValuesFromIntlPropertyProviderTest(
      const GetValuesFromIntlPropertyProviderTest&) = delete;
  GetValuesFromIntlPropertyProviderTest& operator=(
      const GetValuesFromIntlPropertyProviderTest&) = delete;
  ~GetValuesFromIntlPropertyProviderTest() override = default;

 protected:
  std::string GetPrimaryLocaleId() {
    fuchsia::intl::Profile profile =
        GetProfileFromPropertyProvider(std::move(property_provider_ptr_));
    return FuchsiaIntlProfileWatcher::GetPrimaryLocaleIdFromProfile(profile);
  }

  std::string GetPrimaryTimeZoneId() {
    fuchsia::intl::Profile profile =
        GetProfileFromPropertyProvider(std::move(property_provider_ptr_));
    return FuchsiaIntlProfileWatcher::GetPrimaryTimeZoneIdFromProfile(profile);
  }

  static fuchsia::intl::Profile GetProfileFromPropertyProvider(
      ::fuchsia::intl::PropertyProviderSyncPtr property_provider) {
    return FuchsiaIntlProfileWatcher::GetProfileFromPropertyProvider(
        std::move(property_provider));
  }

  ::fuchsia::intl::PropertyProviderSyncPtr property_provider_ptr_;
  FakePropertyProviderAsync property_provider_;
};

class IntlProfileWatcherTest : public testing::Test {
 public:
  IntlProfileWatcherTest()
      : property_provider_(property_provider_ptr_.NewRequest()) {}
  IntlProfileWatcherTest(const IntlProfileWatcherTest&) = delete;
  IntlProfileWatcherTest& operator=(const IntlProfileWatcherTest&) = delete;
  ~IntlProfileWatcherTest() override = default;

 protected:
  base::test::SingleThreadTaskEnvironment task_environment_{
      base::test::SingleThreadTaskEnvironment::MainThreadType::IO};

  std::unique_ptr<FuchsiaIntlProfileWatcher> CreateIntlProfileWatcher(
      FuchsiaIntlProfileWatcher::ProfileChangeCallback on_profile_changed) {
    return base::WrapUnique(new FuchsiaIntlProfileWatcher(
        std::move(property_provider_ptr_), std::move(on_profile_changed)));
  }

  ::fuchsia::intl::PropertyProviderPtr property_provider_ptr_;
  FakePropertyProviderAsync property_provider_;

  base::RunLoop run_loop_;
};

// Unit tests are run in an environment where intl is not provided.
// However, this is not exposed by the API.
TEST(IntlServiceNotAvailableTest, FuchsiaIntlProfileWatcher) {
  base::test::SingleThreadTaskEnvironment task_environment_{
      base::test::SingleThreadTaskEnvironment::MainThreadType::IO};
  base::RunLoop run_loop;

  base::MockCallback<FuchsiaIntlProfileWatcher::ProfileChangeCallback>
      on_profile_changed;
  EXPECT_CALL(on_profile_changed, Run(testing::_)).Times(0);
  auto watcher =
      std::make_unique<FuchsiaIntlProfileWatcher>(on_profile_changed.Get());
  EXPECT_TRUE(watcher);

  run_loop.RunUntilIdle();
}

TEST_F(GetValuesFromIntlPropertyProviderTest,
       GetPrimaryTimeZoneId_RemoteNotBound) {
  // Simulate the service not actually being available.
  property_provider_.Close();
  EXPECT_STREQ("", GetPrimaryTimeZoneId().c_str());
}

TEST_F(GetValuesFromIntlPropertyProviderTest, GetPrimaryTimeZoneId_NoZones) {
  EXPECT_STREQ("", GetPrimaryTimeZoneId().c_str());
}

TEST_F(GetValuesFromIntlPropertyProviderTest, GetPrimaryTimeZoneId_SingleZone) {
  property_provider_.SetTimeZones({kPrimaryTimeZoneName});
  EXPECT_STREQ(kPrimaryTimeZoneName, GetPrimaryTimeZoneId().c_str());
}

TEST_F(GetValuesFromIntlPropertyProviderTest,
       GetPrimaryTimeZoneId_SingleZoneIsEmpty) {
  property_provider_.SetTimeZones({""});
  EXPECT_STREQ("", GetPrimaryTimeZoneId().c_str());
}

TEST_F(GetValuesFromIntlPropertyProviderTest,
       GetPrimaryTimeZoneId_MoreThanOneZone) {
  property_provider_.SetTimeZones(
      {kPrimaryTimeZoneName, kSecondaryTimeZoneName});
  EXPECT_STREQ(kPrimaryTimeZoneName, GetPrimaryTimeZoneId().c_str());
}

TEST_F(GetValuesFromIntlPropertyProviderTest,
       GetPrimaryLocaleId_RemoteNotBound) {
  // Simulate the service not actually being available.
  property_provider_.Close();
  EXPECT_STREQ("", GetPrimaryLocaleId().c_str());
}

TEST_F(GetValuesFromIntlPropertyProviderTest, GetPrimaryLocaleId_NoZones) {
  EXPECT_STREQ("", GetPrimaryLocaleId().c_str());
}

TEST_F(GetValuesFromIntlPropertyProviderTest, GetPrimaryLocaleId_SingleLocale) {
  property_provider_.SetLocales({kPrimaryLocaleName});
  EXPECT_STREQ(kPrimaryLocaleName, GetPrimaryLocaleId().c_str());
}

TEST_F(GetValuesFromIntlPropertyProviderTest,
       GetPrimaryLocaleId_SingleLocaleIsEmpty) {
  property_provider_.SetLocales({""});
  EXPECT_STREQ("", GetPrimaryLocaleId().c_str());
}

TEST_F(GetValuesFromIntlPropertyProviderTest,
       GetPrimaryLocaleId_MoreThanOneLocale) {
  property_provider_.SetLocales({kPrimaryLocaleName, kSecondaryLocaleName});
  EXPECT_STREQ(kPrimaryLocaleName, GetPrimaryLocaleId().c_str());
}

TEST_F(IntlProfileWatcherTest, NoZones_NoNotification) {
  base::MockCallback<FuchsiaIntlProfileWatcher::ProfileChangeCallback> callback;
  EXPECT_CALL(callback, Run(testing::_)).Times(0);
  auto watcher = CreateIntlProfileWatcher(callback.Get());
  run_loop_.RunUntilIdle();
}

TEST_F(IntlProfileWatcherTest, ChangeNotification_AfterInitialization) {
  auto watcher = CreateIntlProfileWatcher(
      base::BindLambdaForTesting([quit_loop = run_loop_.QuitClosure()](
                                     const fuchsia::intl::Profile& profile) {
        EXPECT_EQ(kPrimaryTimeZoneName,
                  FuchsiaIntlProfileWatcher::GetPrimaryTimeZoneIdFromProfile(
                      profile));
        quit_loop.Run();
      }));

  property_provider_.SetTimeZones({kPrimaryTimeZoneName});
  property_provider_.NotifyChange();

  run_loop_.Run();
}

TEST_F(IntlProfileWatcherTest, ChangeNotification_BeforeInitialization) {
  property_provider_.SetTimeZones({kPrimaryTimeZoneName});
  property_provider_.NotifyChange();

  auto watcher = CreateIntlProfileWatcher(
      base::BindLambdaForTesting([quit_loop = run_loop_.QuitClosure()](
                                     const fuchsia::intl::Profile& profile) {
        EXPECT_EQ(kPrimaryTimeZoneName,
                  FuchsiaIntlProfileWatcher::GetPrimaryTimeZoneIdFromProfile(
                      profile));
        quit_loop.Run();
      }));

  run_loop_.Run();
}

// Ensure no crash when the peer service cannot be reached during creation.
TEST_F(IntlProfileWatcherTest, ChannelClosedBeforeCreation) {
  base::MockCallback<FuchsiaIntlProfileWatcher::ProfileChangeCallback> callback;
  EXPECT_CALL(callback, Run(testing::_)).Times(0);

  property_provider_.Close();

  auto watcher = CreateIntlProfileWatcher(callback.Get());

  property_provider_.NotifyChange();
  run_loop_.RunUntilIdle();
}

// Ensure no crash when the channel is closed after creation.
TEST_F(IntlProfileWatcherTest, ChannelClosedAfterCreation) {
  base::MockCallback<FuchsiaIntlProfileWatcher::ProfileChangeCallback> callback;
  EXPECT_CALL(callback, Run(testing::_)).Times(0);

  auto watcher = CreateIntlProfileWatcher(callback.Get());

  property_provider_.Close();

  property_provider_.NotifyChange();
  run_loop_.RunUntilIdle();
}

TEST(IntlProfileWatcherGetPrimaryTimeZoneIdFromProfileTest, NoZones) {
  EXPECT_EQ("", FuchsiaIntlProfileWatcher::GetPrimaryTimeZoneIdFromProfile(
                    fuchsia::intl::Profile()));
}

TEST(IntlProfileWatcherGetPrimaryTimeZoneIdFromProfileTest, EmptyZonesList) {
  EXPECT_EQ("", FuchsiaIntlProfileWatcher::GetPrimaryTimeZoneIdFromProfile(
                    CreateProfileWithTimeZones({})));
}

TEST(IntlProfileWatcherGetPrimaryTimeZoneIdFromProfileTest, OneZone) {
  EXPECT_EQ(kPrimaryTimeZoneName,
            FuchsiaIntlProfileWatcher::GetPrimaryTimeZoneIdFromProfile(
                CreateProfileWithTimeZones({kPrimaryTimeZoneName})));
}

TEST(IntlProfileWatcherGetPrimaryTimeZoneIdFromProfileTest, TwoZones) {
  EXPECT_EQ(kPrimaryTimeZoneName,
            FuchsiaIntlProfileWatcher::GetPrimaryTimeZoneIdFromProfile(
                CreateProfileWithTimeZones(
                    {kPrimaryTimeZoneName, kSecondaryTimeZoneName})));
}

TEST(IntlProfileWatcherGetPrimaryLocaleIdFromProfileTest, NoLocales) {
  EXPECT_EQ("", FuchsiaIntlProfileWatcher::GetPrimaryLocaleIdFromProfile(
                    fuchsia::intl::Profile()));
}

TEST(IntlProfileWatcherGetPrimaryLocaleIdFromProfileTest, EmptyLocalesList) {
  EXPECT_EQ("", FuchsiaIntlProfileWatcher::GetPrimaryLocaleIdFromProfile(
                    CreateProfileWithLocales({})));
}

TEST(IntlProfileWatcherGetPrimaryLocaleIdFromProfileTest, OneLocale) {
  EXPECT_EQ(kPrimaryLocaleName,
            FuchsiaIntlProfileWatcher::GetPrimaryLocaleIdFromProfile(
                CreateProfileWithLocales({kPrimaryLocaleName})));
}

TEST(IntlProfileWatcherGetPrimaryLocaleIdFromProfileTest, MultipleLocales) {
  EXPECT_EQ(kPrimaryLocaleName,
            FuchsiaIntlProfileWatcher::GetPrimaryLocaleIdFromProfile(
                CreateProfileWithLocales(
                    {kPrimaryLocaleName, kSecondaryLocaleName})));
}

}  // namespace base
