// Copyright 2019 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 "src/sys/appmgr/log_connector_impl.h"

#include <lib/fit/function.h>
#include <lib/gtest/real_loop_fixture.h>
#include <lib/syslog/cpp/macros.h>

#include <gtest/gtest.h>

namespace component {
namespace {

class LogConnectorImplTest : public gtest::RealLoopFixture {
 protected:
  LogConnectorImplTest() {}
};

// A LogConnectionListener utility used for testing. Upon construction, takes the consumer using
// thet log connector and forwards any new connections.
class FakeLogConnectionListener : fuchsia::sys::internal::LogConnectionListener {
 public:
  FakeLogConnectionListener(
      LogConnectorImpl* connector_impl,
      fit::function<void(fuchsia::sys::internal::LogConnection)> on_new_connection)
      : binding_(this), on_new_connection_(std::move(on_new_connection)) {
    connector_impl->AddConnectorClient(connector_.NewRequest());
    connector_->TakeLogConnectionListener(
        [&](fidl::InterfaceRequest<fuchsia::sys::internal::LogConnectionListener> req) {
          binding_.Bind(std::move(req));
        });
  }

 private:
  // |fuchsia::sys::internal::LogConnectionListener|
  void OnNewConnection(fuchsia::sys::internal::LogConnection connection) override {
    on_new_connection_(std::move(connection));
  }

  fidl::Binding<fuchsia::sys::internal::LogConnectionListener> binding_;
  fit::function<void(fuchsia::sys::internal::LogConnection)> on_new_connection_;
  fuchsia::sys::internal::LogConnectorPtr connector_;
};

// Test that there can only be one LogConnectionListener connection for a LogConnectorImpl
// per-realm.
TEST_F(LogConnectorImplTest, OneConsumerPerRealm) {
  LogConnectorImpl log_conn_impl("realm1");
  fuchsia::sys::internal::LogConnectorPtr log_conn;

  log_conn_impl.AddConnectorClient(log_conn.NewRequest());

  fidl::InterfaceRequest<fuchsia::sys::internal::LogConnectionListener> consumer_req;
  log_conn->TakeLogConnectionListener(
      [&](fidl::InterfaceRequest<fuchsia::sys::internal::LogConnectionListener> req) {
        consumer_req = std::move(req);
      });
  // Wait until the above TakeLogConnectionListener call responds.
  RunLoopUntil([&] { return consumer_req.is_valid(); });

  // Calling TakeLogConnectionListener() again should return a null request<LogConnectionListener>
  // since we already received a valid one above.
  bool response_received = false;
  fidl::InterfaceRequest<fuchsia::sys::internal::LogConnectionListener> consumer_req2;
  log_conn->TakeLogConnectionListener(
      [&](fidl::InterfaceRequest<fuchsia::sys::internal::LogConnectionListener> req) {
        response_received = true;
        consumer_req2 = std::move(req);
      });
  RunLoopUntil([&] { return response_received; });
  EXPECT_FALSE(consumer_req2.is_valid());
}

// Test that log sinks are attributed per connection, and attributed to a component's identity
// (realm path and component URL).
TEST_F(LogConnectorImplTest, AttributedSourceIdentity) {
  const char kRootRealm[] = "root_realm";
  LogConnectorImpl root(kRootRealm);
  std::vector<fuchsia::sys::internal::LogConnection> connections;
  FakeLogConnectionListener root_log_consumer(
      &root, /* on_new_connection */ [&](fuchsia::sys::internal::LogConnection conn) {
        connections.push_back(std::move(conn));
      });

  const char kChildRealm[] = "child_realm";
  const char kGrandChildRealm[] = "grandchild_realm";
  auto child = root.NewChild(kChildRealm);
  auto grandchild = child->NewChild(kGrandChildRealm);

  fuchsia::logger::LogSinkPtr child_log_sink;
  const char kFakeComponentUrl[] = "fuchsia-pkg://fuchsia.com/test#meta/test.cmx";
  // Add connection and wait until we intercept it
  grandchild->AddLogConnection(kFakeComponentUrl, "-1", child_log_sink.NewRequest());
  RunLoopUntil([&] { return connections.size() == 1; });

  EXPECT_EQ(kFakeComponentUrl, connections[0].source_identity.component_url());
  EXPECT_EQ("test.cmx", connections[0].source_identity.component_name());
  EXPECT_EQ(std::vector<std::string>({kChildRealm, kGrandChildRealm}),
            connections[0].source_identity.realm_path());
}

}  // namespace
}  // namespace component
