// 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 <fcntl.h>
#include <fuchsia/sys/internal/cpp/fidl.h>
#include <fuchsia/sys/internal/cpp/fidl_test_base.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/sys/cpp/testing/fake_component.h>
#include <unistd.h>

#include <gtest/gtest.h>

#include "lib/sys/cpp/testing/component_context_provider.h"
#include "src/lib/files/directory.h"
#include "src/lib/files/scoped_temp_dir.h"
#include "src/lib/fxl/strings/substitute.h"
#include "src/lib/testing/loop_fixture/test_loop_fixture.h"
#include "src/sys/appmgr/component_controller_impl.h"
#include "src/sys/appmgr/component_id_index.h"
#include "src/sys/appmgr/realm.h"

namespace component {
namespace {

// Listener is not discovearble, and needs an explicit name.
const char kListenerName[] = "fuchsia::sys::internal::ComponentEventListener";
const char kEmptyComponentIdIndex[] =
    R"({ "appmgr_restrict_isolated_persistent_storage": false, "instances": [] })";

class FakeListener : public fuchsia::sys::internal::testing::ComponentEventListener_TestBase {
 public:
  FakeListener() { component_.AddPublicService(bindings_.GetHandler(this), kListenerName); }

  void NotImplemented_(const std::string& name) override { FAIL() << "not implemented: " << name; }

 private:
  sys::testing::FakeComponent component_;
  fidl::BindingSet<fuchsia::sys::internal::ComponentEventListener> bindings_;
};

class ComponentEventProviderTest : public ::gtest::TestLoopFixture {
 protected:
  void SetUp() {
    TestLoopFixture::SetUp();
    fake_listener_service_ = std::make_unique<FakeListener>();
    context_provider_ = std::make_unique<sys::testing::ComponentContextProvider>(dispatcher());
  }

  // Borrowed from realm_unittest.cc, consider deduping if things get overly copied around.
  std::unique_ptr<Realm> CreateTestRealm(fbl::unique_fd dirfd) {
    files::CreateDirectoryAt(dirfd.get(), "scheme_map");
    auto environment_services = sys::ServiceDirectory::CreateFromNamespace();
    fuchsia::sys::ServiceListPtr root_realm_services(new fuchsia::sys::ServiceList);
    RealmArgs realm_args = RealmArgs::MakeWithAdditionalServices(
        nullptr, "test", "/data", "/data/cache", "/tmp", std::move(environment_services),
        std::move(root_realm_services), fuchsia::sys::EnvironmentOptions{}, std::move(dirfd),
        ComponentIdIndex::CreateFromIndexContents(kEmptyComponentIdIndex).take_value());
    return Realm::Create(std::move(realm_args));
  }

  files::ScopedTempDir tmp_dir_;
  std::unique_ptr<fuchsia::sys::internal::ComponentEventListener> fake_listener_service_;
  std::unique_ptr<sys::testing::ComponentContextProvider> context_provider_;
};

TEST_F(ComponentEventProviderTest, NotificationAfterShutdownDoesNotCrash) {
  std::string dir;
  ASSERT_TRUE(tmp_dir_.NewTempDir(&dir));
  fbl::unique_fd dirfd(open(dir.c_str(), O_RDONLY));
  std::unique_ptr<Realm> realm = CreateTestRealm(std::move(dirfd));

  fuchsia::sys::internal::ComponentEventListenerPtr client;
  context_provider_->ConnectToPublicService(client.NewRequest(dispatcher()), kListenerName);

  {
    ComponentEventProviderImpl event_provider(realm->weak_ptr(), dispatcher());
    event_provider.SetListener(std::move(client));
    // Let event_provider go out of scope on purpose while still having a listener.
  }
  // Drain events to force the listener callback to fire and try to send notifications to the
  // expired event_provider.
  RunLoopUntilIdle();
}

}  // namespace
}  // namespace component
