// Copyright 2018 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 "base/synchronization/waitable_event.h"
#include "chrome/chrome_cleaner/interfaces/string16_embedded_nulls.mojom.h"
#include "chrome/chrome_cleaner/interfaces/test_string16_embedded_nulls.mojom.h"
#include "chrome/chrome_cleaner/ipc/ipc_test_util.h"
#include "chrome/chrome_cleaner/ipc/mojo_task_runner.h"
#include "chrome/chrome_cleaner/strings/string16_embedded_nulls.h"
#include "chrome/chrome_cleaner/strings/string_test_helpers.h"
#include "chrome/chrome_cleaner/test/test_util.h"
#include "mojo/core/embedder/embedder.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/multiprocess_func_list.h"

namespace chrome_cleaner {

namespace {

using base::WaitableEvent;

class TestString16EmbeddedNullsImpl : public mojom::TestString16EmbeddedNulls {
 public:
  explicit TestString16EmbeddedNullsImpl(
      mojom::TestString16EmbeddedNullsRequest request)
      : binding_(this, std::move(request)) {}

  void Echo(const String16EmbeddedNulls& path, EchoCallback callback) override {
    std::move(callback).Run(path);
  }

 private:
  mojo::Binding<mojom::TestString16EmbeddedNulls> binding_;
};

class SandboxParentProcess : public chrome_cleaner::ParentProcess {
 public:
  explicit SandboxParentProcess(scoped_refptr<MojoTaskRunner> mojo_task_runner)
      : ParentProcess(std::move(mojo_task_runner)) {}

 protected:
  void CreateImpl(mojo::ScopedMessagePipeHandle mojo_pipe) override {
    mojom::TestString16EmbeddedNullsRequest request(std::move(mojo_pipe));
    impl_ = std::make_unique<TestString16EmbeddedNullsImpl>(std::move(request));
  }

  void DestroyImpl() override { impl_.reset(); }

 private:
  ~SandboxParentProcess() override = default;

  std::unique_ptr<TestString16EmbeddedNullsImpl> impl_;
};

class SandboxChildProcess : public chrome_cleaner::ChildProcess {
 public:
  explicit SandboxChildProcess(scoped_refptr<MojoTaskRunner> mojo_task_runner)
      : ChildProcess(mojo_task_runner),
        ptr_(std::make_unique<mojom::TestString16EmbeddedNullsPtr>()) {}

  void BindToPipe(mojo::ScopedMessagePipeHandle mojo_pipe,
                  WaitableEvent* event) {
    ptr_->Bind(chrome_cleaner::mojom::TestString16EmbeddedNullsPtrInfo(
        std::move(mojo_pipe), 0));
    event->Signal();
  }

  bool SuccessfulEcho(const String16EmbeddedNulls& input) {
    String16EmbeddedNulls output;
    WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
                        WaitableEvent::InitialState::NOT_SIGNALED);
    mojo_task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&SandboxChildProcess::RunEcho, base::Unretained(this),
                       input, GetSaveAndSignalCallback(&output, &event)));
    event.Wait();

    return input == output;
  }

 private:
  ~SandboxChildProcess() override {
    mojo_task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(
            [](std::unique_ptr<mojom::TestString16EmbeddedNullsPtr> ptr) {
              ptr.reset();
            },
            base::Passed(&ptr_)));
  }

  template <typename EchoedType>
  base::OnceCallback<void(const EchoedType&)> GetSaveAndSignalCallback(
      EchoedType* output,
      WaitableEvent* event) {
    return base::BindOnce(
        [](EchoedType* value_holder, WaitableEvent* event,
           const EchoedType& value) {
          *value_holder = value;
          event->Signal();
        },
        output, event);
  }

  void RunEcho(const String16EmbeddedNulls& input,
               mojom::TestString16EmbeddedNulls::EchoCallback callback) {
    (*ptr_)->Echo(input, std::move(callback));
  }

  std::unique_ptr<mojom::TestString16EmbeddedNullsPtr> ptr_;
};

scoped_refptr<SandboxChildProcess> InitChildProcess() {
  auto mojo_task_runner = MojoTaskRunner::Create();
  auto child_process =
      base::MakeRefCounted<SandboxChildProcess>(mojo_task_runner);
  auto message_pipe_handle = child_process->CreateMessagePipeFromCommandLine();

  WaitableEvent event(WaitableEvent::ResetPolicy::MANUAL,
                      WaitableEvent::InitialState::NOT_SIGNALED);
  mojo_task_runner->PostTask(
      FROM_HERE, base::BindOnce(&SandboxChildProcess::BindToPipe, child_process,
                                base::Passed(&message_pipe_handle), &event));
  event.Wait();

  return child_process;
}

MULTIPROCESS_TEST_MAIN(EchoMain) {
  scoped_refptr<SandboxChildProcess> child_process = InitChildProcess();

  // Empty string.
  EXPECT_TRUE(child_process->SuccessfulEcho(String16EmbeddedNulls()));
  EXPECT_TRUE(child_process->SuccessfulEcho(String16EmbeddedNulls(nullptr)));
  EXPECT_TRUE(child_process->SuccessfulEcho(String16EmbeddedNulls(nullptr, 0)));
  EXPECT_TRUE(child_process->SuccessfulEcho(String16EmbeddedNulls(nullptr, 1)));
  EXPECT_TRUE(child_process->SuccessfulEcho(String16EmbeddedNulls(L"", 0)));
  EXPECT_TRUE(child_process->SuccessfulEcho(
      String16EmbeddedNulls(std::vector<wchar_t>{})));
  EXPECT_TRUE(
      child_process->SuccessfulEcho(String16EmbeddedNulls(base::string16())));
  EXPECT_TRUE(child_process->SuccessfulEcho(
      String16EmbeddedNulls(base::string16(L""))));
  EXPECT_TRUE(child_process->SuccessfulEcho(
      String16EmbeddedNulls(base::StringPiece16())));
  EXPECT_TRUE(child_process->SuccessfulEcho(
      String16EmbeddedNulls(base::StringPiece16(L""))));

  // Null-terminated strings. Zeroes will be replaced with null characters.
  constexpr wchar_t kStringWithNulls[] = L"string0with0nulls";
  const std::vector<wchar_t> vec1 = CreateVectorWithNulls(kStringWithNulls);
  EXPECT_TRUE(child_process->SuccessfulEcho(
      String16EmbeddedNulls(vec1.data(), vec1.size())));
  EXPECT_TRUE(child_process->SuccessfulEcho(String16EmbeddedNulls(vec1)));
  EXPECT_TRUE(child_process->SuccessfulEcho(
      String16EmbeddedNulls(base::string16(vec1.data(), vec1.size()))));
  EXPECT_TRUE(child_process->SuccessfulEcho(
      String16EmbeddedNulls(base::StringPiece16(vec1.data(), vec1.size()))));

  // Non null-terminated strings.
  const std::vector<wchar_t> vec2(vec1.begin(), vec1.end() - 1);
  EXPECT_TRUE(child_process->SuccessfulEcho(
      String16EmbeddedNulls(vec2.data(), vec2.size())));
  EXPECT_TRUE(child_process->SuccessfulEcho(String16EmbeddedNulls(vec2)));
  EXPECT_TRUE(child_process->SuccessfulEcho(
      String16EmbeddedNulls(base::string16(vec2.data(), vec2.size()))));
  EXPECT_TRUE(child_process->SuccessfulEcho(
      String16EmbeddedNulls(base::StringPiece16(vec2.data(), vec2.size()))));

  return ::testing::Test::HasNonfatalFailure();
}

class String16EmbeddedNullsTypemapTest : public ::testing::Test {
 public:
  void SetUp() override {
    mojo_task_runner_ = MojoTaskRunner::Create();
    parent_process_ =
        base::MakeRefCounted<SandboxParentProcess>(mojo_task_runner_);
  }

 protected:
  scoped_refptr<MojoTaskRunner> mojo_task_runner_;
  scoped_refptr<SandboxParentProcess> parent_process_;
};

TEST_F(String16EmbeddedNullsTypemapTest, Echo) {
  int32_t exit_code = -1;
  EXPECT_TRUE(
      parent_process_->LaunchConnectedChildProcess("EchoMain", &exit_code));
  EXPECT_EQ(0, exit_code);
}

}  // namespace

}  // namespace chrome_cleaner
