// Copyright 2014 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/files/file_proxy.h"

#include <utility>

#include "base/bind.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/threading/thread.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "starboard/memory.h"
#include "starboard/types.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {

class FileProxyTest : public testing::Test {
 public:
  FileProxyTest()
      : file_thread_("FileProxyTestFileThread"),
        error_(File::FILE_OK),
        bytes_written_(-1),
        weak_factory_(this) {}

  void SetUp() override {
    ASSERT_TRUE(dir_.CreateUniqueTempDir());
    ASSERT_TRUE(file_thread_.Start());
  }

  void DidFinish(File::Error error) {
    error_ = error;
    RunLoop::QuitCurrentWhenIdleDeprecated();
  }

  void DidCreateOrOpen(File::Error error) {
    error_ = error;
    RunLoop::QuitCurrentWhenIdleDeprecated();
  }

  void DidCreateTemporary(File::Error error,
                          const FilePath& path) {
    error_ = error;
    path_ = path;
    RunLoop::QuitCurrentWhenIdleDeprecated();
  }

  void DidGetFileInfo(File::Error error,
                      const File::Info& file_info) {
    error_ = error;
    file_info_ = file_info;
    RunLoop::QuitCurrentWhenIdleDeprecated();
  }

  void DidRead(File::Error error,
               const char* data,
               int bytes_read) {
    error_ = error;
    buffer_.resize(bytes_read);
    SbMemoryCopy(&buffer_[0], data, bytes_read);
    RunLoop::QuitCurrentWhenIdleDeprecated();
  }

  void DidWrite(File::Error error,
                int bytes_written) {
    error_ = error;
    bytes_written_ = bytes_written;
    RunLoop::QuitCurrentWhenIdleDeprecated();
  }

 protected:
  void CreateProxy(uint32_t flags, FileProxy* proxy) {
    proxy->CreateOrOpen(
        TestPath(), flags,
        BindOnce(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
    RunLoop().Run();
    EXPECT_TRUE(proxy->IsValid());
  }

  TaskRunner* file_task_runner() const {
    return file_thread_.task_runner().get();
  }
  const FilePath& TestDirPath() const { return dir_.GetPath(); }
  const FilePath TestPath() const { return dir_.GetPath().AppendASCII("test"); }

  ScopedTempDir dir_;
  MessageLoopForIO message_loop_;
  Thread file_thread_;

  File::Error error_;
  FilePath path_;
  File::Info file_info_;
  std::vector<char> buffer_;
  int bytes_written_;
  WeakPtrFactory<FileProxyTest> weak_factory_;
};

TEST_F(FileProxyTest, CreateOrOpen_Create) {
  FileProxy proxy(file_task_runner());
  proxy.CreateOrOpen(
      TestPath(), File::FLAG_CREATE | File::FLAG_READ,
      BindOnce(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
  RunLoop().Run();

  EXPECT_EQ(File::FILE_OK, error_);
  EXPECT_TRUE(proxy.IsValid());
  EXPECT_TRUE(proxy.created());
  EXPECT_TRUE(PathExists(TestPath()));
}

TEST_F(FileProxyTest, CreateOrOpen_Open) {
  // Creates a file.
  base::WriteFile(TestPath(), nullptr, 0);
  ASSERT_TRUE(PathExists(TestPath()));

  // Opens the created file.
  FileProxy proxy(file_task_runner());
  proxy.CreateOrOpen(
      TestPath(), File::FLAG_OPEN | File::FLAG_READ,
      BindOnce(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
  RunLoop().Run();

  EXPECT_EQ(File::FILE_OK, error_);
  EXPECT_TRUE(proxy.IsValid());
  EXPECT_FALSE(proxy.created());
}

TEST_F(FileProxyTest, CreateOrOpen_OpenNonExistent) {
  FileProxy proxy(file_task_runner());
  proxy.CreateOrOpen(
      TestPath(), File::FLAG_OPEN | File::FLAG_READ,
      BindOnce(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
  RunLoop().Run();
  EXPECT_EQ(File::FILE_ERROR_NOT_FOUND, error_);
  EXPECT_FALSE(proxy.IsValid());
  EXPECT_FALSE(proxy.created());
  EXPECT_FALSE(PathExists(TestPath()));
}

TEST_F(FileProxyTest, CreateOrOpen_AbandonedCreate) {
  bool prev = ThreadRestrictions::SetIOAllowed(false);
  {
    FileProxy proxy(file_task_runner());
    proxy.CreateOrOpen(
        TestPath(), File::FLAG_CREATE | File::FLAG_READ,
        BindOnce(&FileProxyTest::DidCreateOrOpen, weak_factory_.GetWeakPtr()));
  }
  RunLoop().Run();
  ThreadRestrictions::SetIOAllowed(prev);

  EXPECT_TRUE(PathExists(TestPath()));
}

TEST_F(FileProxyTest, Close) {
  // Creates a file.
  FileProxy proxy(file_task_runner());
  CreateProxy(File::FLAG_CREATE | File::FLAG_WRITE, &proxy);

#if defined(OS_WIN)
  // This fails on Windows if the file is not closed.
  EXPECT_FALSE(base::Move(TestPath(), TestDirPath().AppendASCII("new")));
#endif

  proxy.Close(BindOnce(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
  RunLoop().Run();
  EXPECT_EQ(File::FILE_OK, error_);
  EXPECT_FALSE(proxy.IsValid());

#if !defined(STARBOARD)
  // Now it should pass on all platforms.
  EXPECT_TRUE(base::Move(TestPath(), TestDirPath().AppendASCII("new")));
#endif
}

TEST_F(FileProxyTest, CreateTemporary) {
  {
    FileProxy proxy(file_task_runner());
    proxy.CreateTemporary(0 /* additional_file_flags */,
                          BindOnce(&FileProxyTest::DidCreateTemporary,
                                   weak_factory_.GetWeakPtr()));
    RunLoop().Run();

    EXPECT_TRUE(proxy.IsValid());
    EXPECT_EQ(File::FILE_OK, error_);
    EXPECT_TRUE(PathExists(path_));

    // The file should be writable.
    proxy.Write(0, "test", 4,
                BindOnce(&FileProxyTest::DidWrite, weak_factory_.GetWeakPtr()));
    RunLoop().Run();
    EXPECT_EQ(File::FILE_OK, error_);
    EXPECT_EQ(4, bytes_written_);
  }

  // Make sure the written data can be read from the returned path.
  std::string data;
  EXPECT_TRUE(ReadFileToString(path_, &data));
  EXPECT_EQ("test", data);

  // Make sure we can & do delete the created file to prevent leaks on the bots.
  EXPECT_TRUE(base::DeleteFile(path_, false));
}

TEST_F(FileProxyTest, SetAndTake) {
  File file(TestPath(), File::FLAG_CREATE | File::FLAG_READ);
  ASSERT_TRUE(file.IsValid());
  FileProxy proxy(file_task_runner());
  EXPECT_FALSE(proxy.IsValid());
  proxy.SetFile(std::move(file));
  EXPECT_TRUE(proxy.IsValid());
  EXPECT_FALSE(file.IsValid());

  file = proxy.TakeFile();
  EXPECT_FALSE(proxy.IsValid());
  EXPECT_TRUE(file.IsValid());
}

#if !defined(STARBOARD)
TEST_F(FileProxyTest, DuplicateFile) {
  FileProxy proxy(file_task_runner());
  CreateProxy(File::FLAG_CREATE | File::FLAG_WRITE, &proxy);
  ASSERT_TRUE(proxy.IsValid());

  base::File duplicate = proxy.DuplicateFile();
  EXPECT_TRUE(proxy.IsValid());
  EXPECT_TRUE(duplicate.IsValid());

  FileProxy invalid_proxy(file_task_runner());
  ASSERT_FALSE(invalid_proxy.IsValid());

  base::File invalid_duplicate = invalid_proxy.DuplicateFile();
  EXPECT_FALSE(invalid_proxy.IsValid());
  EXPECT_FALSE(invalid_duplicate.IsValid());
}
#endif

TEST_F(FileProxyTest, GetInfo) {
  // Setup.
  ASSERT_EQ(4, base::WriteFile(TestPath(), "test", 4));
  File::Info expected_info;
  GetFileInfo(TestPath(), &expected_info);

  // Run.
  FileProxy proxy(file_task_runner());
  CreateProxy(File::FLAG_OPEN | File::FLAG_READ, &proxy);
  proxy.GetInfo(
      BindOnce(&FileProxyTest::DidGetFileInfo, weak_factory_.GetWeakPtr()));
  RunLoop().Run();

  // Verify.
  EXPECT_EQ(File::FILE_OK, error_);
  EXPECT_EQ(expected_info.size, file_info_.size);
  EXPECT_EQ(expected_info.is_directory, file_info_.is_directory);
  EXPECT_EQ(expected_info.is_symbolic_link, file_info_.is_symbolic_link);
  EXPECT_EQ(expected_info.last_modified, file_info_.last_modified);
  EXPECT_EQ(expected_info.creation_time, file_info_.creation_time);
}

TEST_F(FileProxyTest, Read) {
  // Setup.
  const char expected_data[] = "bleh";
  int expected_bytes = arraysize(expected_data);
  ASSERT_EQ(expected_bytes,
            base::WriteFile(TestPath(), expected_data, expected_bytes));

  // Run.
  FileProxy proxy(file_task_runner());
  CreateProxy(File::FLAG_OPEN | File::FLAG_READ, &proxy);

  proxy.Read(0, 128,
             BindOnce(&FileProxyTest::DidRead, weak_factory_.GetWeakPtr()));
  RunLoop().Run();

  // Verify.
  EXPECT_EQ(File::FILE_OK, error_);
  EXPECT_EQ(expected_bytes, static_cast<int>(buffer_.size()));
  for (size_t i = 0; i < buffer_.size(); ++i) {
    EXPECT_EQ(expected_data[i], buffer_[i]);
  }
}

TEST_F(FileProxyTest, WriteAndFlush) {
  FileProxy proxy(file_task_runner());
  CreateProxy(File::FLAG_CREATE | File::FLAG_WRITE, &proxy);

  const char data[] = "foo!";
  int data_bytes = arraysize(data);
  proxy.Write(0, data, data_bytes,
              BindOnce(&FileProxyTest::DidWrite, weak_factory_.GetWeakPtr()));
  RunLoop().Run();
  EXPECT_EQ(File::FILE_OK, error_);
  EXPECT_EQ(data_bytes, bytes_written_);

  // Flush the written data.  (So that the following read should always
  // succeed.  On some platforms it may work with or without this flush.)
  proxy.Flush(BindOnce(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
  RunLoop().Run();
  EXPECT_EQ(File::FILE_OK, error_);

  // Verify the written data.
  char buffer[10];
  EXPECT_EQ(data_bytes, base::ReadFile(TestPath(), buffer, data_bytes));
  for (int i = 0; i < data_bytes; ++i) {
    EXPECT_EQ(data[i], buffer[i]);
  }
}

#if defined(OS_ANDROID) || defined(OS_FUCHSIA) || defined(STARBOARD)
// Flaky on Android, see http://crbug.com/489602
// TODO(crbug.com/851734): Implementation depends on stat, which is not
// implemented on Fuchsia
#define MAYBE_SetTimes DISABLED_SetTimes
#else
#define MAYBE_SetTimes SetTimes
#endif
TEST_F(FileProxyTest, MAYBE_SetTimes) {
  FileProxy proxy(file_task_runner());
  CreateProxy(
      File::FLAG_CREATE | File::FLAG_WRITE | File::FLAG_WRITE_ATTRIBUTES,
      &proxy);

  Time last_accessed_time = Time::Now() - TimeDelta::FromDays(12345);
  Time last_modified_time = Time::Now() - TimeDelta::FromHours(98765);

  proxy.SetTimes(
      last_accessed_time, last_modified_time,
      BindOnce(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
  RunLoop().Run();
  EXPECT_EQ(File::FILE_OK, error_);

  File::Info info;
  GetFileInfo(TestPath(), &info);

  // The returned values may only have the seconds precision, so we cast
  // the double values to int here.
  EXPECT_EQ(static_cast<int>(last_modified_time.ToDoubleT()),
            static_cast<int>(info.last_modified.ToDoubleT()));
  EXPECT_EQ(static_cast<int>(last_accessed_time.ToDoubleT()),
            static_cast<int>(info.last_accessed.ToDoubleT()));
}

TEST_F(FileProxyTest, SetLength_Shrink) {
  // Setup.
  const char kTestData[] = "0123456789";
  ASSERT_EQ(10, base::WriteFile(TestPath(), kTestData, 10));
  File::Info info;
  GetFileInfo(TestPath(), &info);
  ASSERT_EQ(10, info.size);

  // Run.
  FileProxy proxy(file_task_runner());
  CreateProxy(File::FLAG_OPEN | File::FLAG_WRITE, &proxy);
  proxy.SetLength(
      7, BindOnce(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
  RunLoop().Run();

  // Verify.
  GetFileInfo(TestPath(), &info);
  ASSERT_EQ(7, info.size);

  char buffer[7];
  EXPECT_EQ(7, base::ReadFile(TestPath(), buffer, 7));
  int i = 0;
  for (; i < 7; ++i)
    EXPECT_EQ(kTestData[i], buffer[i]);
}

TEST_F(FileProxyTest, SetLength_Expand) {
  // Setup.
  const char kTestData[] = "9876543210";
  ASSERT_EQ(10, base::WriteFile(TestPath(), kTestData, 10));
  File::Info info;
  GetFileInfo(TestPath(), &info);
  ASSERT_EQ(10, info.size);

  // Run.
  FileProxy proxy(file_task_runner());
  CreateProxy(File::FLAG_OPEN | File::FLAG_WRITE, &proxy);
  proxy.SetLength(
      53, BindOnce(&FileProxyTest::DidFinish, weak_factory_.GetWeakPtr()));
  RunLoop().Run();

  // Verify.
  GetFileInfo(TestPath(), &info);
  ASSERT_EQ(53, info.size);

  char buffer[53];
  EXPECT_EQ(53, base::ReadFile(TestPath(), buffer, 53));
  int i = 0;
  for (; i < 10; ++i)
    EXPECT_EQ(kTestData[i], buffer[i]);
  for (; i < 53; ++i)
    EXPECT_EQ(0, buffer[i]);
}

}  // namespace base
