// Copyright (c) 2012 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 <stdint.h>
#include <tuple>

#include "base/files/file_path.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "content/public/test/render_view_test.h"
#include "content/public/test/test_utils.h"
#include "content/renderer/pepper/mock_renderer_ppapi_host.h"
#include "content/renderer/pepper/pepper_file_chooser_host.h"
#include "content/renderer/render_view_impl.h"
#include "content/test/test_content_client.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/host/host_message_context.h"
#include "ppapi/host/ppapi_host.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/resource_message_params.h"
#include "ppapi/proxy/resource_message_test_sink.h"
#include "ppapi/shared_impl/file_ref_create_info.h"
#include "ppapi/shared_impl/ppapi_permissions.h"
#include "ppapi/shared_impl/proxy_lock.h"
#include "ppapi/shared_impl/resource_tracker.h"
#include "ppapi/shared_impl/test_globals.h"
#include "services/service_manager/public/cpp/interface_provider.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/mojom/choosers/file_chooser.mojom.h"

namespace content {

using blink::mojom::FileChooser;
using blink::mojom::FileChooserFileInfo;
using blink::mojom::FileChooserFileInfoPtr;
using blink::mojom::FileChooserParams;
using blink::mojom::FileChooserParamsPtr;
using blink::mojom::FileChooserPtr;
using blink::mojom::FileChooserRequest;

namespace {

class MockFileChooser : public FileChooser {
 public:
  MockFileChooser(service_manager::InterfaceProvider* provider,
                  base::OnceClosure reached_callback)
      : reached_callback_(std::move(reached_callback)) {
    service_manager::InterfaceProvider::TestApi test_api(provider);
    test_api.SetBinderForName(
        FileChooser::Name_,
        base::BindRepeating(&MockFileChooser::OnFileChooserRequest,
                            base::Unretained(this)));
    provider_ = provider;
  }

  ~MockFileChooser() override {
    service_manager::InterfaceProvider::TestApi test_api(provider_);
    test_api.ClearBinderForName(FileChooser::Name_);
  }

  const FileChooserParams& params() const {
    DCHECK(params_);
    return *params_;
  }

  void ResponseOnOpenFileChooser(std::vector<FileChooserFileInfoPtr> files) {
    DCHECK(callback_);
    DCHECK(params_);
    std::move(callback_).Run(blink::mojom::FileChooserResult::New(
        std::move(files), base::FilePath()));
    bindings_.FlushForTesting();
  }

 private:
  void OnFileChooserRequest(mojo::ScopedMessagePipeHandle handle) {
    bindings_.AddBinding(this, FileChooserRequest(std::move(handle)));
  }

  void OpenFileChooser(FileChooserParamsPtr params,
                       OpenFileChooserCallback callback) override {
    callback_ = std::move(callback);
    params_ = std::move(params);
    std::move(reached_callback_).Run();
  }

  void EnumerateChosenDirectory(
      const base::FilePath& directory_path,
      EnumerateChosenDirectoryCallback callback) override {}

  service_manager::InterfaceProvider* provider_;
  mojo::BindingSet<FileChooser> bindings_;
  OpenFileChooserCallback callback_;
  FileChooserParamsPtr params_;
  base::OnceClosure reached_callback_;
};

class PepperFileChooserHostTest : public RenderViewTest {
 public:
  PepperFileChooserHostTest() : pp_instance_(123456) {}

  void SetUp() override {
    SetContentClient(&client_);
    RenderViewTest::SetUp();

    globals_.GetResourceTracker()->DidCreateInstance(pp_instance_);
    mock_file_chooser_ = std::make_unique<MockFileChooser>(
        static_cast<RenderFrameImpl*>(view_->GetMainRenderFrame())
            ->GetInterfaceProvider(),
        run_loop_.QuitClosure());
  }
  void TearDown() override {
    mock_file_chooser_.reset();
    globals_.GetResourceTracker()->DidDeleteInstance(pp_instance_);

    RenderViewTest::TearDown();
  }

  PP_Instance pp_instance() const { return pp_instance_; }
  MockFileChooser* mock_file_chooser() const {
    return mock_file_chooser_.get();
  }

 protected:
  base::RunLoop run_loop_;

 private:
  PP_Instance pp_instance_;

  // Disables locking for the duration of the test.
  ppapi::ProxyLock::LockingDisablerForTest disable_locking_;
  ppapi::TestGlobals globals_;
  TestContentClient client_;

  std::unique_ptr<MockFileChooser> mock_file_chooser_;
};

}  // namespace

TEST_F(PepperFileChooserHostTest, Show) {
  PP_Resource pp_resource = 123;

  MockRendererPpapiHost host(view_, pp_instance());
  PepperFileChooserHost chooser(&host, pp_instance(), pp_resource);

  // Say there's a user gesture.
  host.set_has_user_gesture(true);

  std::vector<std::string> accept;
  accept.push_back("text/plain");
  PpapiHostMsg_FileChooser_Show show_msg(false, false, std::string(), accept);

  ppapi::proxy::ResourceMessageCallParams call_params(pp_resource, 0);
  ppapi::host::HostMessageContext context(call_params);
  int32_t result = chooser.OnResourceMessageReceived(show_msg, &context);
  EXPECT_EQ(PP_OK_COMPLETIONPENDING, result);

  run_loop_.Run();
  // The render view should have sent a chooser request to the browser

  // Basic validation of request.
  auto& params = mock_file_chooser()->params();
  EXPECT_EQ(FileChooserParams::Mode::kOpen, params.mode);
  ASSERT_EQ(1u, params.accept_types.size());
  EXPECT_EQ(accept[0], base::UTF16ToUTF8(params.accept_types[0]));

  // Send a chooser reply to the render view. Note our reply path has to have a
  // path separator so we include both a Unix and a Windows one.
  std::vector<blink::mojom::FileChooserFileInfoPtr> selected_info_vector;
  base::string16 display_name = base::ASCIIToUTF16("Hello, world");
  selected_info_vector.push_back(
      blink::mojom::FileChooserFileInfo::NewNativeFile(
          blink::mojom::NativeFileInfo::New(
              base::FilePath(FILE_PATH_LITERAL("myp\\ath/foo")),
              display_name)));
  mock_file_chooser()->ResponseOnOpenFileChooser(
      std::move(selected_info_vector));

  // This should have sent the Pepper reply to our test sink.
  ppapi::proxy::ResourceMessageReplyParams reply_params;
  IPC::Message reply_msg;
  ASSERT_TRUE(host.sink().GetFirstResourceReplyMatching(
      PpapiPluginMsg_FileChooser_ShowReply::ID, &reply_params, &reply_msg));

  // Basic validation of reply.
  EXPECT_EQ(call_params.sequence(), reply_params.sequence());
  EXPECT_EQ(PP_OK, reply_params.result());
  PpapiPluginMsg_FileChooser_ShowReply::Schema::Param reply_msg_param;
  ASSERT_TRUE(
      PpapiPluginMsg_FileChooser_ShowReply::Read(&reply_msg, &reply_msg_param));
  const std::vector<ppapi::FileRefCreateInfo>& chooser_results =
      std::get<0>(reply_msg_param);
  ASSERT_EQ(1u, chooser_results.size());
  EXPECT_EQ(base::UTF16ToUTF8(display_name), chooser_results[0].display_name);
}

TEST_F(PepperFileChooserHostTest, NoUserGesture) {
  PP_Resource pp_resource = 123;

  MockRendererPpapiHost host(view_, pp_instance());
  PepperFileChooserHost chooser(&host, pp_instance(), pp_resource);

  // Say there's no user gesture.
  host.set_has_user_gesture(false);

  std::vector<std::string> accept;
  accept.push_back("text/plain");
  PpapiHostMsg_FileChooser_Show show_msg(false, false, std::string(), accept);

  ppapi::proxy::ResourceMessageCallParams call_params(pp_resource, 0);
  ppapi::host::HostMessageContext context(call_params);
  int32_t result = chooser.OnResourceMessageReceived(show_msg, &context);
  EXPECT_EQ(PP_ERROR_NO_USER_GESTURE, result);
}

}  // namespace content
