// 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 <utility>

#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;

// Share the application URL with multiple application tests.
String g_url;

// 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, const char** argv) {
  MOJO_CHECK(g_args.is_null());
  for (int i = 0; i < argc; i++) {
    MOJO_CHECK(argv[i]);
    g_args.push_back(argv[i]);
  }
}

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(InterfaceHandle<Shell> shell,
                  Array<String> args,
                  const mojo::String& url) override {
    *args_ = args.Pass();
    g_url = url;
    g_application_request = binding_.Unbind();
    g_shell = ShellPtr::Create(std::move(shell));
  }

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

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

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

}  // namespace

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, InterfaceRequest<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;

    // Note: |InitGoogleTest()| will modify |argc| and |argv[...]|.
    testing::InitGoogleTest(&argc, const_cast<char**>(&argv[0]));
    InitializeArgs(argc, &argv[0]);

    Environment::DestroyDefaultRunLoop();
  }

  int result = RUN_ALL_TESTS();

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

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

ApplicationTestBase::ApplicationTestBase() {}

ApplicationTestBase::~ApplicationTestBase() {}

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);
  MOJO_CHECK(args_.empty());

  shell_ = g_shell.Pass();
  for (size_t i = 0; i < g_args.size(); i++)
    args_.push_back(g_args[i]);
}

void ApplicationTestBase::TearDown() {
  MOJO_CHECK(!g_shell);

  // TODO(vtl): The straightforward |g_shell = shell_.Pass();| causes tests to
  // hang. Presumably, it's because there are still requests to the shell
  // pending. :-(
  g_shell.Bind(shell_.PassInterfaceHandle());
  args_.clear();

  if (ShouldCreateDefaultRunLoop())
    Environment::DestroyDefaultRunLoop();
}

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

}  // namespace test
}  // namespace mojo
