// Copyright 2019 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 "services/data_decoder/bundled_exchanges_parser_factory.h"

#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/optional.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace data_decoder {

namespace {

base::FilePath GetTestFilePath(const base::FilePath& path) {
  base::FilePath test_path;
  base::PathService::Get(base::DIR_SOURCE_ROOT, &test_path);
  test_path = test_path.Append(base::FilePath(
      FILE_PATH_LITERAL("services/test/data/bundled_exchanges")));
  return test_path.Append(path);
}

}  // namespace

class BundledExchangesParserFactoryTest : public testing::Test {
 public:
  BundledExchangesParserFactoryTest()
      : factory_(std::make_unique<BundledExchangesParserFactory>(
            /*service_ref=*/nullptr)) {}

  std::unique_ptr<mojom::BundleDataSource> CreateFileDataSource(
      mojo::PendingReceiver<mojom::BundleDataSource> receiver,
      base::File file) {
    return factory_->CreateFileDataSourceForTesting(std::move(receiver),
                                                    std::move(file));
  }

  void GetParserForFile(
      mojo::PendingReceiver<mojom::BundledExchangesParser> receiver,
      base::File file) {
    mojom::BundledExchangesParserFactory* factory = factory_.get();
    return factory->GetParserForFile(std::move(receiver), std::move(file));
  }

 private:
  std::unique_ptr<BundledExchangesParserFactory> factory_;
  base::test::ScopedTaskEnvironment task_environment_;
};

TEST_F(BundledExchangesParserFactoryTest, GetSize) {
  base::FilePath test_file = base::FilePath(FILE_PATH_LITERAL("hello.wbn"));

  base::File file(GetTestFilePath(test_file),
                  base::File::FLAG_OPEN | base::File::FLAG_READ);
  ASSERT_TRUE(file.IsValid());
  uint64_t file_size = file.GetLength();

  mojo::PendingRemote<mojom::BundleDataSource> remote;
  auto data_source = CreateFileDataSource(
      remote.InitWithNewPipeAndPassReceiver(), std::move(file));

  uint64_t result_size;
  base::RunLoop run_loop;
  data_source->GetSize(
      base::BindLambdaForTesting([&result_size, &run_loop](uint64_t size) {
        result_size = size;
        run_loop.QuitClosure().Run();
      }));
  run_loop.Run();

  EXPECT_EQ(file_size, result_size);
}

TEST_F(BundledExchangesParserFactoryTest, Read) {
  base::FilePath test_file =
      GetTestFilePath(base::FilePath(FILE_PATH_LITERAL("hello.wbn")));

  base::File file(test_file, base::File::FLAG_OPEN | base::File::FLAG_READ);
  ASSERT_TRUE(file.IsValid());
  int64_t file_length = file.GetLength();
  constexpr int64_t test_length = 16;
  ASSERT_LE(test_length, file_length);
  std::vector<uint8_t> first16b(test_length);
  ASSERT_EQ(test_length, file.Read(0, reinterpret_cast<char*>(first16b.data()),
                                   first16b.size()));
  std::vector<uint8_t> last16b(test_length);
  ASSERT_EQ(test_length,
            file.Read(file_length - test_length,
                      reinterpret_cast<char*>(last16b.data()), last16b.size()));

  mojo::PendingRemote<mojom::BundleDataSource> remote;
  auto data_source = CreateFileDataSource(
      remote.InitWithNewPipeAndPassReceiver(), std::move(file));

  base::Optional<std::vector<uint8_t>> result_data;
  {
    base::RunLoop run_loop;
    data_source->Read(
        /*offset=*/0, test_length,
        base::BindLambdaForTesting(
            [&result_data,
             &run_loop](const base::Optional<std::vector<uint8_t>>& data) {
              result_data = data;
              run_loop.QuitClosure().Run();
            }));
    run_loop.Run();
  }
  ASSERT_TRUE(result_data);
  EXPECT_EQ(first16b, *result_data);

  {
    base::RunLoop run_loop;
    data_source->Read(
        file_length - test_length, test_length,
        base::BindLambdaForTesting(
            [&result_data,
             &run_loop](const base::Optional<std::vector<uint8_t>>& data) {
              result_data = data;
              run_loop.QuitClosure().Run();
            }));
    run_loop.Run();
  }
  ASSERT_TRUE(result_data);
  EXPECT_EQ(last16b, *result_data);

  {
    base::RunLoop run_loop;
    data_source->Read(
        file_length - test_length, test_length + 1,
        base::BindLambdaForTesting(
            [&result_data,
             &run_loop](const base::Optional<std::vector<uint8_t>>& data) {
              result_data = data;
              run_loop.QuitClosure().Run();
            }));
    run_loop.Run();
  }
  ASSERT_FALSE(result_data);
}

TEST_F(BundledExchangesParserFactoryTest, GetParserForFile) {
  base::File file(
      GetTestFilePath(base::FilePath(FILE_PATH_LITERAL("hello.wbn"))),
      base::File::FLAG_OPEN | base::File::FLAG_READ);
  ASSERT_TRUE(file.IsValid());

  mojo::Remote<mojom::BundledExchangesParser> parser;
  GetParserForFile(parser.BindNewPipeAndPassReceiver(), std::move(file));

  mojom::BundleMetadataPtr metadata;
  {
    base::RunLoop run_loop;
    parser->ParseMetadata(base::BindLambdaForTesting(
        [&metadata, &run_loop](mojom::BundleMetadataPtr metadata_ptr,
                               const base::Optional<std::string>& error) {
          metadata = std::move(metadata_ptr);
          run_loop.QuitClosure().Run();
        }));
    run_loop.Run();
  }
  ASSERT_TRUE(metadata);
  ASSERT_EQ(metadata->index.size(), 4u);

  const auto& index = metadata->index;

  std::vector<mojom::BundleResponsePtr> responses;
  for (size_t i = 0; i < index.size(); i++) {
    base::RunLoop run_loop;
    parser->ParseResponse(
        index[i]->response_offset, index[i]->response_length,
        base::BindLambdaForTesting(
            [&responses, &run_loop](mojom::BundleResponsePtr response,
                                    const base::Optional<std::string>& error) {
              ASSERT_TRUE(response);
              ASSERT_FALSE(error);
              responses.push_back(std::move(response));
              run_loop.QuitClosure().Run();
            }));
    run_loop.Run();
  }
  EXPECT_EQ(index[0]->request_url, "https://test.example.org/");
  EXPECT_EQ(index[0]->request_method, "GET");
  EXPECT_EQ(index[0]->request_headers.size(), 0u);
  EXPECT_EQ(responses[0]->response_code, 200);
  EXPECT_EQ(responses[0]->response_headers["content-type"],
            "text/html; charset=utf-8");
  EXPECT_EQ(index[1]->request_url, "https://test.example.org/index.html");
  EXPECT_EQ(index[2]->request_url,
            "https://test.example.org/manifest.webmanifest");
  EXPECT_EQ(index[3]->request_url, "https://test.example.org/script.js");
}

}  // namespace data_decoder
