// Copyright 2022 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/component/cpp/fidl.h>
#include <fuchsia/component/decl/cpp/fidl.h>
#include <fuchsia/examples/services/cpp/fidl.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/sys/service/cpp/service.h>
#include <lib/sys/service/cpp/service_aggregate.h>
#include <lib/syslog/cpp/log_settings.h>
#include <lib/syslog/cpp/macros.h>

#include <gtest/gtest.h>
#include <src/lib/testing/loop_fixture/real_loop_fixture.h>

class BankAccountTest : public ::gtest::RealLoopFixture {
 public:
  explicit BankAccountTest() {
    // Connect to the fuchsia.component.Realm framework protocol
    sys::ComponentContext::Create()->svc()->Connect(realm_proxy_.NewRequest());
  }

  // Create and instance of the provider component and return its exposed directory
  fuchsia::io::DirectorySyncPtr StartProvider(const char* component_name,
                                              const char* component_url) {
    FX_LOG_KV(INFO, "Creating BankAccount provider", FX_KV("url", component_url),
              FX_KV("name", component_name));
    fuchsia::component::decl::CollectionRef collection_ref = {
        .name = "account_providers",
    };
    fuchsia::component::decl::Child child_decl;
    child_decl.set_name(component_name);
    child_decl.set_url(component_url);
    child_decl.set_startup(fuchsia::component::decl::StartupMode::LAZY);

    fuchsia::component::Realm_CreateChild_Result create_result;
    realm_proxy_->CreateChild(std::move(collection_ref), std::move(child_decl),
                              fuchsia::component::CreateChildArgs(), &create_result);

    FX_LOG_KV(INFO, "Open exposed dir of BankAccount provider", FX_KV("url", component_url),
              FX_KV("name", component_name));
    fuchsia::component::decl::ChildRef child_ref = {
        .name = component_name,
        .collection = "account_providers",
    };
    fuchsia::io::DirectorySyncPtr exposed_dir;
    fuchsia::component::Realm_OpenExposedDir_Result open_result;
    realm_proxy_->OpenExposedDir(child_ref, exposed_dir.NewRequest(), &open_result);

    return exposed_dir;
  }

 private:
  fuchsia::component::RealmSyncPtr realm_proxy_;
};

TEST_F(BankAccountTest, ReadWriteMultipleServiceInstances) {
  // Launch two BankAccount providers into the `account_providers` collection.
  StartProvider("a", "provider-a#meta/default.cm");
  StartProvider("b", "provider-b#meta/default.cm");

  // List available instances of the BankAccount service
  auto service_aggregate = sys::OpenServiceAggregate<fuchsia::examples::services::BankAccount>();
  auto instance_names = service_aggregate.ListInstances();
  ZX_ASSERT(!instance_names.empty());

  // Debit both bank accounts by $5.
  for (auto& instance : instance_names) {
    auto service = sys::OpenService<fuchsia::examples::services::BankAccount>(instance);
    // Connect to the ReadOnlyAccount protocol offered by this service
    fuchsia::examples::services::ReadOnlyAccountSyncPtr read_only_account =
        service.read_only().Connect().BindSync();
    std::string initial_owner;
    read_only_account->GetOwner(&initial_owner);
    int64_t initial_balance;
    read_only_account->GetBalance(&initial_balance);
    FX_LOGS(INFO) << "Retrieved account: " << initial_owner;

    // Connect to the ReadWriteAccount protocol offered by this service
    fuchsia::examples::services::ReadWriteAccountSyncPtr read_write_account =
        service.read_write().Connect().BindSync();
    std::string owner;
    read_write_account->GetOwner(&owner);
    ASSERT_EQ(initial_owner, owner);
    int64_t balance;
    read_write_account->GetBalance(&balance);
    ASSERT_EQ(initial_balance, balance);

    FX_LOGS(INFO) << "Debiting account: " << owner;
    bool success;
    read_write_account->Debit(5, &success);
    ASSERT_TRUE(success);
    read_write_account->GetBalance(&balance);
    ASSERT_EQ(initial_balance - 5, balance);
  }
}
