// 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 "net/base/upload_file_element_reader.h"

#include <limits>

#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/test/gtest_util.h"
#include "net/test/test_with_scoped_task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

#if defined(OS_MACOSX)
#include "base/mac/scoped_nsautorelease_pool.h"
#include "starboard/types.h"
#endif

using net::test::IsError;
using net::test::IsOk;

namespace net {

// When the parameter is false, the UploadFileElementReader is passed only a
// FilePath and needs to open the file itself. When it's true, it's passed an
// already open base::File.
class UploadFileElementReaderTest : public testing::TestWithParam<bool>,
                                    public WithScopedTaskEnvironment {
 protected:
  void SetUp() override {
    // Some tests (*.ReadPartially) rely on bytes_.size() being even.
    bytes_.assign({'1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c',
                   'd', 'e', 'f', 'g', 'h', 'i'});

    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());

    ASSERT_TRUE(
        base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &temp_file_path_));
    ASSERT_EQ(
        static_cast<int>(bytes_.size()),
        base::WriteFile(temp_file_path_, &bytes_[0], bytes_.size()));

    reader_ =
        CreateReader(0, std::numeric_limits<uint64_t>::max(), base::Time());

    TestCompletionCallback callback;
    ASSERT_THAT(reader_->Init(callback.callback()), IsError(ERR_IO_PENDING));
    EXPECT_THAT(callback.WaitForResult(), IsOk());
    EXPECT_EQ(bytes_.size(), reader_->GetContentLength());
    EXPECT_EQ(bytes_.size(), reader_->BytesRemaining());
    EXPECT_FALSE(reader_->IsInMemory());
  }

  ~UploadFileElementReaderTest() override {
    reader_.reset();
    base::RunLoop().RunUntilIdle();
  }

  // Creates a UploadFileElementReader based on the value of GetParam().
  std::unique_ptr<UploadFileElementReader> CreateReader(
      int64_t offset,
      int64_t length,
      base::Time expected_modification_time) {
    if (GetParam()) {
      return std::make_unique<UploadFileElementReader>(
          base::ThreadTaskRunnerHandle::Get().get(), temp_file_path_, offset,
          length, expected_modification_time);
    }

    // The base::File::FLAG_SHARE_DELETE lets the file be deleted without the
    // test fixture waiting on it to be closed.
    int open_flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
                     base::File::FLAG_SHARE_DELETE;
#if defined(OS_WIN)
    // On Windows, file must be opened for asynchronous operation.
    open_flags |= base::File::FLAG_ASYNC;
#endif  // defined(OS_WIN)

    base::File file(temp_file_path_, open_flags);
    EXPECT_TRUE(file.IsValid());
    return std::make_unique<UploadFileElementReader>(
        base::ThreadTaskRunnerHandle::Get().get(), std::move(file),
        // Use an incorrect path, to make sure that the file is never re-opened.
        base::FilePath(FILE_PATH_LITERAL("this_should_be_ignored")), offset,
        length, expected_modification_time);
  }

#if defined(OS_MACOSX)
  // May be needed to avoid leaks on OSX.
  base::mac::ScopedNSAutoreleasePool scoped_pool_;
#endif

  std::vector<char> bytes_;
  std::unique_ptr<UploadElementReader> reader_;
  base::ScopedTempDir temp_dir_;
  base::FilePath temp_file_path_;
};

TEST_P(UploadFileElementReaderTest, ReadPartially) {
  const size_t kHalfSize = bytes_.size() / 2;
  ASSERT_EQ(bytes_.size(), kHalfSize * 2);
  std::vector<char> buf(kHalfSize);
  scoped_refptr<IOBuffer> wrapped_buffer =
      base::MakeRefCounted<WrappedIOBuffer>(&buf[0]);
  TestCompletionCallback read_callback1;
  ASSERT_EQ(ERR_IO_PENDING,
            reader_->Read(
                wrapped_buffer.get(), buf.size(), read_callback1.callback()));
  EXPECT_EQ(static_cast<int>(buf.size()), read_callback1.WaitForResult());
  EXPECT_EQ(bytes_.size() - buf.size(), reader_->BytesRemaining());
  EXPECT_EQ(std::vector<char>(bytes_.begin(), bytes_.begin() + kHalfSize), buf);

  TestCompletionCallback read_callback2;
  EXPECT_EQ(ERR_IO_PENDING,
            reader_->Read(
                wrapped_buffer.get(), buf.size(), read_callback2.callback()));
  EXPECT_EQ(static_cast<int>(buf.size()), read_callback2.WaitForResult());
  EXPECT_EQ(0U, reader_->BytesRemaining());
  EXPECT_EQ(std::vector<char>(bytes_.begin() + kHalfSize, bytes_.end()), buf);
}

TEST_P(UploadFileElementReaderTest, ReadAll) {
  std::vector<char> buf(bytes_.size());
  scoped_refptr<IOBuffer> wrapped_buffer =
      base::MakeRefCounted<WrappedIOBuffer>(&buf[0]);
  TestCompletionCallback read_callback;
  ASSERT_EQ(ERR_IO_PENDING,
            reader_->Read(
                wrapped_buffer.get(), buf.size(), read_callback.callback()));
  EXPECT_EQ(static_cast<int>(buf.size()), read_callback.WaitForResult());
  EXPECT_EQ(0U, reader_->BytesRemaining());
  EXPECT_EQ(bytes_, buf);
  // Try to read again.
  EXPECT_EQ(0,
            reader_->Read(
                wrapped_buffer.get(), buf.size(), read_callback.callback()));
}

TEST_P(UploadFileElementReaderTest, ReadTooMuch) {
  const size_t kTooLargeSize = bytes_.size() * 2;
  std::vector<char> buf(kTooLargeSize);
  scoped_refptr<IOBuffer> wrapped_buffer =
      base::MakeRefCounted<WrappedIOBuffer>(&buf[0]);
  TestCompletionCallback read_callback;
  ASSERT_EQ(ERR_IO_PENDING,
            reader_->Read(
                wrapped_buffer.get(), buf.size(), read_callback.callback()));
  EXPECT_EQ(static_cast<int>(bytes_.size()), read_callback.WaitForResult());
  EXPECT_EQ(0U, reader_->BytesRemaining());
  buf.resize(bytes_.size());  // Resize to compare.
  EXPECT_EQ(bytes_, buf);
}

TEST_P(UploadFileElementReaderTest, MultipleInit) {
  std::vector<char> buf(bytes_.size());
  scoped_refptr<IOBuffer> wrapped_buffer =
      base::MakeRefCounted<WrappedIOBuffer>(&buf[0]);

  // Read all.
  TestCompletionCallback read_callback1;
  ASSERT_EQ(ERR_IO_PENDING,
            reader_->Read(
                wrapped_buffer.get(), buf.size(), read_callback1.callback()));
  EXPECT_EQ(static_cast<int>(buf.size()), read_callback1.WaitForResult());
  EXPECT_EQ(0U, reader_->BytesRemaining());
  EXPECT_EQ(bytes_, buf);

  // Call Init() again to reset the state.
  TestCompletionCallback init_callback;
  ASSERT_THAT(reader_->Init(init_callback.callback()), IsError(ERR_IO_PENDING));
  EXPECT_THAT(init_callback.WaitForResult(), IsOk());
  EXPECT_EQ(bytes_.size(), reader_->GetContentLength());
  EXPECT_EQ(bytes_.size(), reader_->BytesRemaining());

  // Read again.
  TestCompletionCallback read_callback2;
  ASSERT_EQ(ERR_IO_PENDING,
            reader_->Read(
                wrapped_buffer.get(), buf.size(), read_callback2.callback()));
  EXPECT_EQ(static_cast<int>(buf.size()), read_callback2.WaitForResult());
  EXPECT_EQ(0U, reader_->BytesRemaining());
  EXPECT_EQ(bytes_, buf);
}

TEST_P(UploadFileElementReaderTest, InitDuringAsyncOperation) {
  std::vector<char> buf(bytes_.size());
  scoped_refptr<IOBuffer> wrapped_buffer =
      base::MakeRefCounted<WrappedIOBuffer>(&buf[0]);

  // Start reading all.
  TestCompletionCallback read_callback1;
  EXPECT_EQ(ERR_IO_PENDING,
            reader_->Read(
                wrapped_buffer.get(), buf.size(), read_callback1.callback()));

  // Call Init to cancel the previous read.
  TestCompletionCallback init_callback1;
  EXPECT_THAT(reader_->Init(init_callback1.callback()),
              IsError(ERR_IO_PENDING));

  // Call Init again to cancel the previous init.
  TestCompletionCallback init_callback2;
  EXPECT_THAT(reader_->Init(init_callback2.callback()),
              IsError(ERR_IO_PENDING));
  EXPECT_THAT(init_callback2.WaitForResult(), IsOk());
  EXPECT_EQ(bytes_.size(), reader_->GetContentLength());
  EXPECT_EQ(bytes_.size(), reader_->BytesRemaining());

  // Read half.
  std::vector<char> buf2(bytes_.size() / 2);
  scoped_refptr<IOBuffer> wrapped_buffer2 =
      base::MakeRefCounted<WrappedIOBuffer>(&buf2[0]);
  TestCompletionCallback read_callback2;
  EXPECT_EQ(ERR_IO_PENDING,
            reader_->Read(
                wrapped_buffer2.get(), buf2.size(), read_callback2.callback()));
  EXPECT_EQ(static_cast<int>(buf2.size()), read_callback2.WaitForResult());
  EXPECT_EQ(bytes_.size() - buf2.size(), reader_->BytesRemaining());
  EXPECT_EQ(std::vector<char>(bytes_.begin(), bytes_.begin() + buf2.size()),
            buf2);

  // Make sure callbacks are not called for cancelled operations.
  EXPECT_FALSE(read_callback1.have_result());
  EXPECT_FALSE(init_callback1.have_result());
}

TEST_P(UploadFileElementReaderTest, RepeatedInitDuringInit) {
  std::vector<char> buf(bytes_.size());
  scoped_refptr<IOBuffer> wrapped_buffer =
      base::MakeRefCounted<WrappedIOBuffer>(&buf[0]);

  TestCompletionCallback init_callback1;
  EXPECT_THAT(reader_->Init(init_callback1.callback()),
              IsError(ERR_IO_PENDING));

  // Call Init again to cancel the previous init.
  TestCompletionCallback init_callback2;
  EXPECT_THAT(reader_->Init(init_callback2.callback()),
              IsError(ERR_IO_PENDING));

  // Call Init yet again to cancel the previous init.
  TestCompletionCallback init_callback3;
  EXPECT_THAT(reader_->Init(init_callback3.callback()),
              IsError(ERR_IO_PENDING));

  EXPECT_THAT(init_callback3.WaitForResult(), IsOk());
  EXPECT_EQ(bytes_.size(), reader_->GetContentLength());
  EXPECT_EQ(bytes_.size(), reader_->BytesRemaining());

  // Read all.
  TestCompletionCallback read_callback;
  int result =
      reader_->Read(wrapped_buffer.get(), buf.size(), read_callback.callback());
  EXPECT_EQ(static_cast<int>(buf.size()), read_callback.GetResult(result));
  EXPECT_EQ(0U, reader_->BytesRemaining());
  EXPECT_EQ(bytes_, buf);

  EXPECT_FALSE(init_callback1.have_result());
  EXPECT_FALSE(init_callback2.have_result());
}

TEST_P(UploadFileElementReaderTest, Range) {
  const uint64_t kOffset = 2;
  const uint64_t kLength = bytes_.size() - kOffset * 3;
  reader_ = CreateReader(kOffset, kLength, base::Time());
  TestCompletionCallback init_callback;
  ASSERT_THAT(reader_->Init(init_callback.callback()), IsError(ERR_IO_PENDING));
  EXPECT_THAT(init_callback.WaitForResult(), IsOk());
  EXPECT_EQ(kLength, reader_->GetContentLength());
  EXPECT_EQ(kLength, reader_->BytesRemaining());
  std::vector<char> buf(kLength);
  scoped_refptr<IOBuffer> wrapped_buffer =
      base::MakeRefCounted<WrappedIOBuffer>(&buf[0]);
  TestCompletionCallback read_callback;
  ASSERT_EQ(
      ERR_IO_PENDING,
      reader_->Read(wrapped_buffer.get(), kLength, read_callback.callback()));
  EXPECT_EQ(static_cast<int>(kLength), read_callback.WaitForResult());
  const std::vector<char> expected(bytes_.begin() + kOffset,
                                   bytes_.begin() + kOffset + kLength);
  EXPECT_EQ(expected, buf);
}

TEST_P(UploadFileElementReaderTest, FileChanged) {
  base::File::Info info;
  ASSERT_TRUE(base::GetFileInfo(temp_file_path_, &info));

  // Expect one second before the actual modification time to simulate change.
  const base::Time expected_modification_time =
      info.last_modified - base::TimeDelta::FromSeconds(1);
  reader_ = CreateReader(0, std::numeric_limits<uint64_t>::max(),
                         expected_modification_time);
  TestCompletionCallback init_callback;
  ASSERT_THAT(reader_->Init(init_callback.callback()), IsError(ERR_IO_PENDING));
  EXPECT_THAT(init_callback.WaitForResult(), IsError(ERR_UPLOAD_FILE_CHANGED));
}

TEST_P(UploadFileElementReaderTest, InexactExpectedTimeStamp) {
  base::File::Info info;
  ASSERT_TRUE(base::GetFileInfo(temp_file_path_, &info));

  const base::Time expected_modification_time =
      info.last_modified - base::TimeDelta::FromMilliseconds(900);
  reader_ = CreateReader(0, std::numeric_limits<uint64_t>::max(),
                         expected_modification_time);
  TestCompletionCallback init_callback;
  ASSERT_THAT(reader_->Init(init_callback.callback()), IsError(ERR_IO_PENDING));
  EXPECT_THAT(init_callback.WaitForResult(), IsOk());
}

TEST_P(UploadFileElementReaderTest, WrongPath) {
  const base::FilePath wrong_path(FILE_PATH_LITERAL("wrong_path"));
  reader_ = std::make_unique<UploadFileElementReader>(
      base::ThreadTaskRunnerHandle::Get().get(), wrong_path, 0,
      std::numeric_limits<uint64_t>::max(), base::Time());
  TestCompletionCallback init_callback;
  ASSERT_THAT(reader_->Init(init_callback.callback()), IsError(ERR_IO_PENDING));
#if defined(STARBOARD)
  // Starboard does not guarantee that all platforms will return specific
  // error code. Some can only gurantee the general ERR_FAILED.
  auto result = init_callback.WaitForResult();
  EXPECT_TRUE(result == ERR_FILE_NOT_FOUND || result == ERR_FAILED);
#else
  EXPECT_THAT(init_callback.WaitForResult(), IsError(ERR_FILE_NOT_FOUND));
#endif
}

#ifdef STARBOARD
bool values[] = {false, true};
INSTANTIATE_TEST_CASE_P(,
                        UploadFileElementReaderTest,
                        testing::ValuesIn(values));
#else
INSTANTIATE_TEST_CASE_P(,
                        UploadFileElementReaderTest,
                        testing::ValuesIn({false, true}));
#endif

}  // namespace net
