// Copyright 2014 The Chromium 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 "mojo/public/cpp/application/application_test_base.h"

#include "mojo/public/cpp/application/application_impl.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "mojo/public/cpp/environment/environment.h"
#include "mojo/public/cpp/system/message_pipe.h"
#include "mojo/public/interfaces/application/application.mojom.h"

namespace mojo {
namespace test {

namespace {
// Share the application command-line arguments with multiple application tests.
Array<String> g_args;

// Application request handle passed from the shell in MojoMain, stored in
// between SetUp()/TearDown() so we can (re-)intialize new ApplicationImpls.
InterfaceRequest<Application> g_application_request;

// Shell pointer passed in the initial mojo.Application.Initialize() call,
// stored in between initial setup and the first test and between SetUp/TearDown
// calls so we can (re-)initialize new ApplicationImpls.
ShellPtr g_shell;

void InitializeArgs(int argc, std::vector<const char*> argv) {
  MOJO_CHECK(g_args.is_null());
  for (const char* arg : argv) {
    if (arg)
      g_args.push_back(arg);
  }
}

class ShellAndArgumentGrabber : public Application {
 public:
  ShellAndArgumentGrabber(Array<String>* args,
                          InterfaceRequest<Application> application_request)
      : args_(args), binding_(this, application_request.Pass()) {}

  void WaitForInitialize() {
    // Initialize is always the first call made on Application.
    MOJO_CHECK(binding_.WaitForIncomingMethodCall());
  }

 private:
  // Application implementation.
  void Initialize(ShellPtr shell,
                  Array<String> args,
                  const mojo::String& url) override {
    *args_ = args.Pass();
    g_application_request = binding_.Unbind();
    g_shell = shell.Pass();
  }

  void AcceptConnection(const String& requestor_url,
                        InterfaceRequest<ServiceProvider> services,
                        ServiceProviderPtr exposed_services) override {
    MOJO_CHECK(false);
  }

  void RequestQuit() override { MOJO_CHECK(false); }

  Array<String>* args_;
  Binding<Application> binding_;
};

}  // namespace

const Array<String>& Args() {
  return g_args;
}

MojoResult RunAllTests(MojoHandle application_request_handle) {
  {
    // This loop is used for init, and then destroyed before running tests.
    Environment::InstantiateDefaultRunLoop();

    // Grab the shell handle and GTEST commandline arguments.
    // GTEST command line arguments are supported amid application arguments:
    // $ mojo_shell mojo:example_apptests
    //   --args-for='mojo:example_apptests arg1 --gtest_filter=foo arg2'
    Array<String> args;
    ShellAndArgumentGrabber grabber(
        &args, MakeRequest<Application>(MakeScopedHandle(
                   MessagePipeHandle(application_request_handle))));
    grabber.WaitForInitialize();
    MOJO_CHECK(g_shell);
    MOJO_CHECK(g_application_request.is_pending());

    // InitGoogleTest expects (argc + 1) elements, including a terminating null.
    // It also removes GTEST arguments from |argv| and updates the |argc| count.
    MOJO_CHECK(args.size() <
               static_cast<size_t>(std::numeric_limits<int>::max()));
    int argc = static_cast<int>(args.size());
    std::vector<const char*> argv(argc + 1);
    for (int i = 0; i < argc; ++i)
      argv[i] = args[i].get().c_str();
    argv[argc] = nullptr;

    testing::InitGoogleTest(&argc, const_cast<char**>(&(argv[0])));
    InitializeArgs(argc, argv);

    Environment::DestroyDefaultRunLoop();
  }

  int result = RUN_ALL_TESTS();

  // Shut down our message pipes before exiting.
  (void)g_application_request.PassMessagePipe();
  (void)g_shell.PassMessagePipe();

  return (result == 0) ? MOJO_RESULT_OK : MOJO_RESULT_UNKNOWN;
}

ApplicationTestBase::ApplicationTestBase() : application_impl_(nullptr) {
}

ApplicationTestBase::~ApplicationTestBase() {
}

ApplicationDelegate* ApplicationTestBase::GetApplicationDelegate() {
  return &default_application_delegate_;
}

void ApplicationTestBase::SetUp() {
  // A run loop is recommended for ApplicationImpl initialization and
  // communication.
  if (ShouldCreateDefaultRunLoop())
    Environment::InstantiateDefaultRunLoop();

  MOJO_CHECK(g_application_request.is_pending());
  MOJO_CHECK(g_shell);

  // New applications are constructed for each test to avoid persisting state.
  application_impl_ = new ApplicationImpl(GetApplicationDelegate(),
                                          g_application_request.Pass());

  // Fake application initialization with the given command line arguments.
  application_impl_->Initialize(g_shell.Pass(), g_args.Clone(), "");
}

void ApplicationTestBase::TearDown() {
  MOJO_CHECK(!g_application_request.is_pending());
  MOJO_CHECK(!g_shell);

  application_impl_->UnbindConnections(&g_application_request, &g_shell);
  delete application_impl_;
  if (ShouldCreateDefaultRunLoop())
    Environment::DestroyDefaultRunLoop();
}

bool ApplicationTestBase::ShouldCreateDefaultRunLoop() {
  return true;
}

}  // namespace test
}  // namespace mojo
