// Copyright 2021 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 "components/pdf/browser/plugin_response_writer.h"

#include <stddef.h>

#include <memory>
#include <string>
#include <utility>

#include "base/callback.h"
#include "base/callback_helpers.h"
#include "base/run_loop.h"
#include "base/test/mock_callback.h"
#include "base/test/task_environment.h"
#include "components/pdf/browser/mock_url_loader_client.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/system/data_pipe.h"
#include "mojo/public/cpp/system/data_pipe_drainer.h"
#include "net/base/net_errors.h"
#include "services/network/public/cpp/url_loader_completion_status.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace pdf {

namespace {

using ::testing::HasSubstr;
using ::testing::NiceMock;

class BodyDrainer {
 public:
  explicit BodyDrainer(mojo::ScopedDataPipeConsumerHandle body)
      : drainer_(&drainer_client_, std::move(body)) {}

  const std::string& content() const { return drainer_client_.content; }

  void WaitComplete() {
    if (drainer_client_.is_complete)
      return;

    base::RunLoop run_loop;
    ASSERT_FALSE(drainer_client_.quit_closure);
    drainer_client_.quit_closure = run_loop.QuitClosure();
    run_loop.Run();

    EXPECT_TRUE(drainer_client_.is_complete);
  }

 private:
  struct DrainerClient : public mojo::DataPipeDrainer::Client {
    void OnDataAvailable(const void* data, size_t num_bytes) override {
      content.append(reinterpret_cast<const char*>(data), num_bytes);
    }

    void OnDataComplete() override {
      is_complete = true;
      if (quit_closure)
        std::move(quit_closure).Run();
    }

    std::string content;
    bool is_complete = false;
    base::OnceClosure quit_closure;
  };

  DrainerClient drainer_client_;
  mojo::DataPipeDrainer drainer_;
};

class PluginResponseWriterTest : public testing::Test {
 protected:
  PluginResponseWriterTest() {
    ON_CALL(mock_client_, OnStartLoadingResponseBody)
        .WillByDefault([this](mojo::ScopedDataPipeConsumerHandle body) {
          body_drainer_ = std::make_unique<BodyDrainer>(std::move(body));
        });
  }

  std::unique_ptr<PluginResponseWriter> NewPluginResponseWriter(
      const GURL& source_url,
      const GURL& original_url) {
    return std::make_unique<PluginResponseWriter>(
        source_url, original_url, client_receiver_.BindNewPipeAndPassRemote());
  }

  base::test::TaskEnvironment task_environment_;
  NiceMock<MockURLLoaderClient> mock_client_;
  mojo::Receiver<network::mojom::URLLoaderClient> client_receiver_{
      &mock_client_};

  std::unique_ptr<BodyDrainer> body_drainer_;
};

}  // namespace

TEST_F(PluginResponseWriterTest, Start) {
  auto response_writer =
      NewPluginResponseWriter(GURL("chrome-extension://id/stream-url"),
                              GURL("https://example.test/fake.pdf"));

  base::RunLoop run_loop;

  {
    // Note that `URLLoaderClient` operations are received on a separate
    // sequence, and only are ordered with respect to each other.
    testing::InSequence in_sequence;

    EXPECT_CALL(mock_client_, OnReceiveResponse)
        .WillOnce([](network::mojom::URLResponseHeadPtr head) {
          EXPECT_EQ("text/html", head->mime_type);
        });

    EXPECT_CALL(mock_client_, OnStartLoadingResponseBody);

    EXPECT_CALL(mock_client_, OnComplete)
        .WillOnce(
            [&run_loop](const network::URLLoaderCompletionStatus& status) {
              EXPECT_EQ(net::OK, status.error_code);
              run_loop.Quit();
            });
  }

  // Note that `done_callback` is not ordered with respect to the
  // `URLLoaderClient` operations.
  base::MockCallback<base::OnceClosure> done_callback;
  EXPECT_CALL(done_callback, Run);

  response_writer->Start(done_callback.Get());
  run_loop.Run();

  // Waiting for `URLLoaderClient::OnComplete()` ensures `body_drainer_` is set,
  // but the data pipe may still have unread data.
  ASSERT_TRUE(body_drainer_);
  body_drainer_->WaitComplete();

  EXPECT_THAT(body_drainer_->content(),
              HasSubstr("src=\"chrome-extension://id/stream-url\""));
  EXPECT_THAT(body_drainer_->content(),
              HasSubstr("original-url=\"https://example.test/fake.pdf\""));
  EXPECT_THAT(body_drainer_->content(), HasSubstr("'chrome-extension://id/'"));
}

TEST_F(PluginResponseWriterTest, StartWithUnescapedUrls) {
  auto response_writer =
      NewPluginResponseWriter(GURL("chrome-extension://id/stream-url\""),
                              GURL("https://example.test/\"fake.pdf"));

  base::RunLoop run_loop;
  EXPECT_CALL(mock_client_, OnComplete).WillOnce([&run_loop]() {
    run_loop.Quit();
  });
  response_writer->Start(base::DoNothing());
  run_loop.Run();

  // Waiting for `URLLoaderClient::OnComplete()` ensures `body_drainer_` is set,
  // but the data pipe may still have unread data.
  ASSERT_TRUE(body_drainer_);
  body_drainer_->WaitComplete();

  EXPECT_THAT(body_drainer_->content(),
              HasSubstr("src=\"chrome-extension://id/stream-url%22\""));
  EXPECT_THAT(body_drainer_->content(),
              HasSubstr("original-url=\"https://example.test/%22fake.pdf\""));
  EXPECT_THAT(body_drainer_->content(), HasSubstr("'chrome-extension://id/'"));
}

TEST_F(PluginResponseWriterTest, StartForPrintPreview) {
  auto response_writer =
      NewPluginResponseWriter(GURL("chrome://print/1/0/print.pdf"),
                              GURL("chrome://print/1/0/print.pdf"));

  base::RunLoop run_loop;
  EXPECT_CALL(mock_client_, OnComplete).WillOnce([&run_loop]() {
    run_loop.Quit();
  });
  response_writer->Start(base::DoNothing());
  run_loop.Run();

  // Waiting for `URLLoaderClient::OnComplete()` ensures `body_drainer_` is set,
  // but the data pipe may still have unread data.
  ASSERT_TRUE(body_drainer_);
  body_drainer_->WaitComplete();

  EXPECT_THAT(body_drainer_->content(),
              HasSubstr("src=\"chrome://print/1/0/print.pdf\""));
  EXPECT_THAT(body_drainer_->content(),
              HasSubstr("original-url=\"chrome://print/1/0/print.pdf\""));
  EXPECT_THAT(body_drainer_->content(), HasSubstr("'chrome://print/'"));
}

}  // namespace pdf
