// Copyright 2018 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 "garnet/examples/fidl/echo_client_cpp/echo_client_app.h"

#include <lib/async/dispatcher.h>
#include <lib/fidl/cpp/binding_set.h>
#include <lib/gtest/test_loop_fixture.h>
#include <lib/sys/cpp/component_context.h>
#include <lib/sys/cpp/testing/component_context_provider.h>
#include <lib/sys/cpp/testing/fake_component.h>
#include <lib/sys/cpp/testing/fake_launcher.h>
#include <memory>

// This test file demonstrates how to use |ComponentContextProvider|.

namespace echo {
namespace testing {

using fidl::examples::echo::Echo;
using fidl::examples::echo::EchoPtr;

// Fake server, which the client under test will be used against
class FakeEcho : public Echo {
 public:
  static const char kURL[];

  fidl::InterfaceRequestHandler<Echo> GetHandler() {
    return bindings_.GetHandler(this);
  }

  FakeEcho() { component_.AddPublicService(bindings_.GetHandler(this)); }

  // Fake implementation of server-side logic
  void EchoString(fidl::StringPtr value, EchoStringCallback callback) {
    callback(answer_);
  }

  void SetAnswer(fidl::StringPtr answer) { answer_ = answer; }

  // Register to be launched with a fake URL
  void Register(sys::testing::FakeLauncher& fake_launcher) {
    component_.Register(kURL, fake_launcher);
  }

 private:
  sys::testing::FakeComponent component_;
  fidl::BindingSet<Echo> bindings_;
  fidl::StringPtr answer_;
};

const char FakeEcho::kURL[] = "fake-echo";

class EchoClientAppForTest : public EchoClientApp {
 public:
  // Expose injecting constructor so we can pass an instrumented Context
  EchoClientAppForTest(std::unique_ptr<sys::ComponentContext> context)
      : EchoClientApp(std::move(context)) {}
};

class TestWithContextExampleTest : public gtest::TestLoopFixture {
 public:
  // Creates a fake echo component and registers it with fake launcher so that
  // when app under test tries to launch echo server, it launches our fake
  // component.
  void SetUp() override {
    TestLoopFixture::SetUp();
    echoClientApp_.reset(new EchoClientAppForTest(provider_.TakeContext()));
    provider_.service_directory_provider()->AddService(
        fake_launcher_.GetHandler());

    fake_echo_.reset(new FakeEcho());
    fake_echo_->Register(fake_launcher_);
  }

  void TearDown() override {
    echoClientApp_.reset();
    TestLoopFixture::TearDown();
  }

 protected:
  void Start(std::string server_url) { echoClientApp_->Start(server_url); }
  EchoPtr& echo() { return echoClientApp_->echo(); }
  void SetAnswer(fidl::StringPtr answer) { fake_echo_->SetAnswer(answer); }

 private:
  std::unique_ptr<EchoClientAppForTest> echoClientApp_;
  std::unique_ptr<FakeEcho> fake_echo_;
  sys::testing::FakeLauncher fake_launcher_;
  sys::testing::ComponentContextProvider provider_;
};

// Demonstrates use of fake component and launcher when component is not
// actually started.
TEST_F(TestWithContextExampleTest, EchoString_HelloWorld_GoodbyeWorld) {
  fidl::StringPtr message = "bogus";
  Start(FakeEcho::kURL);
  SetAnswer("Goodbye World!");
  echo()->EchoString("Hello World!",
                     [&](::fidl::StringPtr retval) { message = retval; });
  RunLoopUntilIdle();
  EXPECT_EQ("Goodbye World!", message);
}

// Demonstrates coorect use of fake component and fake launcher.
// In this we are not starting echo service so we will not get any reply from
// server.
TEST_F(TestWithContextExampleTest, EchoString_NoStart) {
  fidl::StringPtr message = "bogus";
  echo()->EchoString("Hello World!",
                     [&](::fidl::StringPtr retval) { message = retval; });
  RunLoopUntilIdle();
  EXPECT_EQ("bogus", message);
}

// This fixture will directly put fake service inside incoming service of mocked
// start up context. This way client under test can directly connect to that
// service using component context.
class FakeEchoInContextExampleTest : public gtest::TestLoopFixture {
 public:
  // Adds a fake echo service to incoming service of mocked component context.
  void SetUp() override {
    TestLoopFixture::SetUp();
    fake_echo_.reset(new FakeEcho());
    provider_.service_directory_provider()->AddService(
        fake_echo_->GetHandler());
  }

  void TearDown() override { TestLoopFixture::TearDown(); }

 protected:
  void SetAnswer(fidl::StringPtr answer) { fake_echo_->SetAnswer(answer); }
  EchoPtr echo() { return provider_.context()->svc()->Connect<Echo>(); }

 private:
  std::unique_ptr<FakeEcho> fake_echo_;
  sys::testing::ComponentContextProvider provider_;
};

// Demonstrates how to directly add fake services to incoming directory of
// mocked out context and then how to connect to it to use it.
//
// This example can be used to test apps which connect to services using
// component context.
TEST_F(FakeEchoInContextExampleTest, EchoString_HelloWorld_GoodbyeWorld) {
  fidl::StringPtr message = "bogus";
  SetAnswer("Goodbye World!");
  auto echo_ptr = echo();
  echo_ptr->EchoString("Hello World!",
                       [&](::fidl::StringPtr retval) { message = retval; });
  RunLoopUntilIdle();
  EXPECT_EQ("Goodbye World!", message);
}

}  // namespace testing
}  // namespace echo
