// Copyright (c) 2011 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 "ppapi/tests/test_file_ref.h"

#include <stddef.h>
#include <stdio.h>

#include <sstream>
#include <vector>

#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppb_file_io.h"
#include "ppapi/c/private/ppb_testing_private.h"
#include "ppapi/cpp/directory_entry.h"
#include "ppapi/cpp/file_io.h"
#include "ppapi/cpp/file_ref.h"
#include "ppapi/cpp/file_system.h"
#include "ppapi/cpp/instance.h"
#include "ppapi/cpp/module.h"
#include "ppapi/cpp/url_loader.h"
#include "ppapi/cpp/url_request_info.h"
#include "ppapi/cpp/url_response_info.h"
#include "ppapi/tests/test_utils.h"
#include "ppapi/tests/testing_instance.h"

REGISTER_TEST_CASE(FileRef);

namespace {

const char* kPersFileName = "persistent";
const char* kTempFileName = "temporary";
const char* kParentPath = "/foo/bar";
const char* kPersFilePath = "/foo/bar/persistent";
const char* kTempFilePath = "/foo/bar/temporary";
const char* kTerribleName = "!@#$%^&*()-_=+{}[] ;:'\"|`~\t\n\r\b?";

typedef std::vector<pp::DirectoryEntry> DirEntries;

std::string ReportMismatch(const std::string& method_name,
                           const std::string& returned_result,
                           const std::string& expected_result) {
  return method_name + " returned '" + returned_result + "'; '" +
      expected_result + "' expected.";
}

}  // namespace

bool TestFileRef::Init() {
  return CheckTestingInterface() && EnsureRunningOverHTTP();
}

std::string TestFileRef::MakeExternalFileRef(pp::FileRef* file_ref_ext) {
  pp::URLRequestInfo request(instance_);
  request.SetURL("test_url_loader_data/hello.txt");
  request.SetStreamToFile(true);

  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::URLLoader loader(instance_);
  callback.WaitForResult(loader.Open(request, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::URLResponseInfo response_info(loader.GetResponseInfo());
  ASSERT_FALSE(response_info.is_null());
  ASSERT_EQ(200, response_info.GetStatusCode());

  *file_ref_ext = pp::FileRef(response_info.GetBodyAsFileRef());
  ASSERT_EQ(PP_FILESYSTEMTYPE_EXTERNAL, file_ref_ext->GetFileSystemType());
  PASS();
}

int32_t TestFileRef::DeleteDirectoryRecursively(pp::FileRef* dir) {
  if (!dir)
    return PP_ERROR_BADARGUMENT;

  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  TestCompletionCallbackWithOutput<DirEntries> output_callback(
      instance_->pp_instance(), callback_type());

  output_callback.WaitForResult(
      dir->ReadDirectoryEntries(output_callback.GetCallback()));
  int32_t rv = output_callback.result();
  if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND)
    return rv;

  DirEntries entries = output_callback.output();
  for (DirEntries::const_iterator it = entries.begin();
       it != entries.end();
       ++it) {
    pp::FileRef file_ref = it->file_ref();
    if (it->file_type() == PP_FILETYPE_DIRECTORY) {
      rv = DeleteDirectoryRecursively(&file_ref);
      if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND)
        return rv;
    } else {
      callback.WaitForResult(file_ref.Delete(callback.GetCallback()));
      rv = callback.result();
      if (rv != PP_OK && rv != PP_ERROR_FILENOTFOUND)
        return rv;
    }
  }
  callback.WaitForResult(dir->Delete(callback.GetCallback()));
  return callback.result();
}

void TestFileRef::RunTests(const std::string& filter) {
  RUN_CALLBACK_TEST(TestFileRef, Create, filter);
  RUN_CALLBACK_TEST(TestFileRef, GetFileSystemType, filter);
  RUN_CALLBACK_TEST(TestFileRef, GetName, filter);
  RUN_CALLBACK_TEST(TestFileRef, GetPath, filter);
  RUN_CALLBACK_TEST(TestFileRef, GetParent, filter);
  RUN_CALLBACK_TEST(TestFileRef, MakeDirectory, filter);
  RUN_CALLBACK_TEST(TestFileRef, QueryAndTouchFile, filter);
  RUN_CALLBACK_TEST(TestFileRef, DeleteFileAndDirectory, filter);
  RUN_CALLBACK_TEST(TestFileRef, RenameFileAndDirectory, filter);
  RUN_CALLBACK_TEST(TestFileRef, Query, filter);
  RUN_CALLBACK_TEST(TestFileRef, FileNameEscaping, filter);
  RUN_CALLBACK_TEST(TestFileRef, ReadDirectoryEntries, filter);
}

std::string TestFileRef::TestCreate() {
  std::vector<std::string> invalid_paths;
  invalid_paths.push_back("invalid_path");  // no '/' at the first character
  invalid_paths.push_back(std::string());   // empty path
  // The following are directory traversal checks
  invalid_paths.push_back("..");
  invalid_paths.push_back("/../invalid_path");
  invalid_paths.push_back("/../../invalid_path");
  invalid_paths.push_back("/invalid/../../path");
  const size_t num_invalid_paths = invalid_paths.size();

  pp::FileSystem file_system_pers(
      instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
  pp::FileSystem file_system_temp(
      instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  for (size_t j = 0; j < num_invalid_paths; ++j) {
    pp::FileRef file_ref_pers(file_system_pers, invalid_paths[j].c_str());
    if (file_ref_pers.pp_resource() != 0) {
      return "file_ref_pers expected to be invalid for path: " +
          invalid_paths[j];
    }
    pp::FileRef file_ref_temp(file_system_temp, invalid_paths[j].c_str());
    if (file_ref_temp.pp_resource() != 0) {
      return "file_ref_temp expected to be invalid for path: " +
          invalid_paths[j];
    }
  }
  PASS();
}

std::string TestFileRef::TestGetFileSystemType() {
  pp::FileSystem file_system_pers(
      instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
  pp::FileSystem file_system_temp(
      instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);

  pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
  if (file_ref_pers.GetFileSystemType() != PP_FILESYSTEMTYPE_LOCALPERSISTENT)
    return "file_ref_pers expected to be persistent.";

  pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
  if (file_ref_temp.GetFileSystemType() != PP_FILESYSTEMTYPE_LOCALTEMPORARY)
    return "file_ref_temp expected to be temporary.";

  pp::FileRef file_ref_ext;
  std::string result = MakeExternalFileRef(&file_ref_ext);
  if (!result.empty())
    return result;
  PASS();
}

std::string TestFileRef::TestGetName() {
  pp::FileSystem file_system_pers(
      instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
  pp::FileSystem file_system_temp(
      instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);

  pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
  std::string name = file_ref_pers.GetName().AsString();
  if (name != kPersFileName)
    return ReportMismatch("FileRef::GetName", name, kPersFileName);

  pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
  name = file_ref_temp.GetName().AsString();
  if (name != kTempFileName)
    return ReportMismatch("FileRef::GetName", name, kTempFileName);

  // Test the "/" case.
  pp::FileRef file_ref_slash(file_system_temp, "/");
  name = file_ref_slash.GetName().AsString();
  if (name != "/")
    return ReportMismatch("FileRef::GetName", name, "/");

  pp::URLRequestInfo request(instance_);
  request.SetURL("test_url_loader_data/hello.txt");
  request.SetStreamToFile(true);

  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::URLLoader loader(instance_);
  callback.WaitForResult(loader.Open(request, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::URLResponseInfo response_info(loader.GetResponseInfo());
  ASSERT_FALSE(response_info.is_null());
  ASSERT_EQ(200, response_info.GetStatusCode());

  pp::FileRef file_ref_ext(response_info.GetBodyAsFileRef());
  name = file_ref_ext.GetName().AsString();
  ASSERT_FALSE(name.empty());

  PASS();
}

std::string TestFileRef::TestGetPath() {
  pp::FileSystem file_system_pers(
      instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
  pp::FileSystem file_system_temp(
      instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);

  pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
  ASSERT_EQ(kPersFilePath, file_ref_pers.GetPath().AsString());

  pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
  ASSERT_EQ(kTempFilePath, file_ref_temp.GetPath().AsString());

  pp::URLRequestInfo request(instance_);
  request.SetURL("test_url_loader_data/hello.txt");
  request.SetStreamToFile(true);

  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::URLLoader loader(instance_);
  callback.WaitForResult(loader.Open(request, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::URLResponseInfo response_info(loader.GetResponseInfo());
  ASSERT_FALSE(response_info.is_null());
  ASSERT_EQ(200, response_info.GetStatusCode());

  pp::FileRef file_ref_ext(response_info.GetBodyAsFileRef());
  ASSERT_TRUE(file_ref_ext.GetPath().is_undefined());

  PASS();
}

std::string TestFileRef::TestGetParent() {
  pp::FileSystem file_system_pers(
      instance_, PP_FILESYSTEMTYPE_LOCALPERSISTENT);
  pp::FileSystem file_system_temp(
      instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);

  pp::FileRef file_ref_pers(file_system_pers, kPersFilePath);
  ASSERT_EQ(kParentPath, file_ref_pers.GetParent().GetPath().AsString());

  pp::FileRef file_ref_temp(file_system_temp, kTempFilePath);
  ASSERT_EQ(kParentPath, file_ref_temp.GetParent().GetPath().AsString());

  // Test the "/" case.
  pp::FileRef file_ref_slash(file_system_temp, "/");
  ASSERT_EQ("/", file_ref_slash.GetParent().GetPath().AsString());

  // Test the "/foo" case (the parent is "/").
  pp::FileRef file_ref_with_root_parent(file_system_temp, "/foo");
  ASSERT_EQ("/", file_ref_with_root_parent.GetParent().GetPath().AsString());

  pp::URLRequestInfo request(instance_);
  request.SetURL("test_url_loader_data/hello.txt");
  request.SetStreamToFile(true);

  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::URLLoader loader(instance_);
  callback.WaitForResult(loader.Open(request, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::URLResponseInfo response_info(loader.GetResponseInfo());
  ASSERT_FALSE(response_info.is_null());
  ASSERT_EQ(200, response_info.GetStatusCode());

  pp::FileRef file_ref_ext(response_info.GetBodyAsFileRef());
  ASSERT_TRUE(file_ref_ext.GetParent().is_null());

  PASS();
}

std::string TestFileRef::TestMakeDirectory() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  // Open.
  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Make a directory.
  pp::FileRef dir_ref(file_system, "/dir_make_dir");
  callback.WaitForResult(
      dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Make a directory on the existing path without exclusive flag.
  callback.WaitForResult(
      dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Making a directory should be aborted.
  int32_t rv = PP_ERROR_FAILED;
  {
    rv = pp::FileRef(file_system, "/dir_make_dir_abort")
        .MakeDirectory(PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback());
  }
  callback.WaitForAbortResult(rv);
  CHECK_CALLBACK_BEHAVIOR(callback);

  // Make nested directories.
  dir_ref = pp::FileRef(file_system, "/dir_make_nested_dir_1/dir");
  callback.WaitForResult(
      dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_WITH_ANCESTORS,
                            callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  dir_ref = pp::FileRef(file_system, "/dir_make_nested_dir_2/dir");
  callback.WaitForResult(
      dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_ERROR_FILENOTFOUND, callback.result());

  // Ensure there is no directory on the path to test exclusive cases.
  dir_ref = pp::FileRef(file_system, "/dir_make_dir_exclusive");
  rv = DeleteDirectoryRecursively(&dir_ref);
  ASSERT_TRUE(rv == PP_OK || rv == PP_ERROR_FILENOTFOUND);

  // Make a directory exclusively.
  callback.WaitForResult(
      dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_EXCLUSIVE,
                            callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  callback.WaitForResult(
      dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_EXCLUSIVE,
                            callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_ERROR_FILEEXISTS, callback.result());

  PASS();
}

std::string TestFileRef::TestQueryAndTouchFile() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileRef file_ref(file_system, "/file_touch");
  pp::FileIO file_io(instance_);
  callback.WaitForResult(
      file_io.Open(file_ref,
                   PP_FILEOPENFLAG_CREATE |
                   PP_FILEOPENFLAG_TRUNCATE |
                   PP_FILEOPENFLAG_WRITE,
                   callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Write some data to have a non-zero file size.
  callback.WaitForResult(file_io.Write(0, "test", 4, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(4, callback.result());

  // Touch.
  const PP_Time last_access_time = 123 * 24 * 3600.0;
  // last_modified_time's granularity is 2 seconds
  // See note in test_file_io.cc for why we use this time.
  const PP_Time last_modified_time = 100 * 24 * 3600.0;
  callback.WaitForResult(file_ref.Touch(last_access_time, last_modified_time,
                                        callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Touch aborted.
  int32_t rv = PP_ERROR_FAILED;
  {
    rv = pp::FileRef(file_system, "/file_touch_abort")
        .Touch(last_access_time, last_modified_time, callback.GetCallback());
  }
  callback.WaitForResult(rv);
  CHECK_CALLBACK_BEHAVIOR(callback);
  if (rv == PP_OK_COMPLETIONPENDING) {
    // Touch tried to run asynchronously and should have been aborted.
    ASSERT_EQ(PP_ERROR_ABORTED, callback.result());
  } else {
    // Touch ran synchronously and should have failed because the file does not
    // exist.
    ASSERT_EQ(PP_ERROR_FILENOTFOUND, callback.result());
  }

  // Query.
  PP_FileInfo info;
  callback.WaitForResult(file_io.Query(&info, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());
  ASSERT_EQ(4, info.size);
  ASSERT_EQ(PP_FILETYPE_REGULAR, info.type);
  ASSERT_EQ(PP_FILESYSTEMTYPE_LOCALTEMPORARY, info.system_type);

  // Disabled due to DST-related failure: crbug.com/314579
  // ASSERT_EQ(last_access_time, info.last_access_time);
  // ASSERT_EQ(last_modified_time, info.last_modified_time);

  // Cancellation test.
  // TODO(viettrungluu): this test causes a bunch of LOG(WARNING)s; investigate.
  // TODO(viettrungluu): check |info| for late writes.
  {
    rv = pp::FileRef(file_system, "/file_touch").Touch(
        last_access_time, last_modified_time, callback.GetCallback());
  }
  callback.WaitForAbortResult(rv);
  CHECK_CALLBACK_BEHAVIOR(callback);

  PASS();
}

std::string TestFileRef::TestDeleteFileAndDirectory() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileRef file_ref(file_system, "/file_delete");
  pp::FileIO file_io(instance_);
  callback.WaitForResult(
      file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  callback.WaitForResult(file_ref.Delete(callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileRef dir_ref(file_system, "/dir_delete");
  callback.WaitForResult(dir_ref.MakeDirectory(
      PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  callback.WaitForResult(dir_ref.Delete(callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileRef nested_dir_ref(file_system, "/dir_delete_1/dir_delete_2");
  callback.WaitForResult(
      nested_dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_WITH_ANCESTORS,
                                   callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Attempt to delete the parent directory (should fail; it's non-empty).
  pp::FileRef parent_dir_ref = nested_dir_ref.GetParent();
  callback.WaitForResult(parent_dir_ref.Delete(callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_ERROR_FAILED, callback.result());

  pp::FileRef nonexistent_file_ref(file_system, "/nonexistent_file_delete");
  callback.WaitForResult(nonexistent_file_ref.Delete(callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_ERROR_FILENOTFOUND, callback.result());

  // Delete aborted.
  int32_t rv = PP_ERROR_FAILED;
  {
    pp::FileRef file_ref_abort(file_system, "/file_delete_abort");
    pp::FileIO file_io_abort(instance_);
    callback.WaitForResult(
        file_io_abort.Open(file_ref_abort, PP_FILEOPENFLAG_CREATE,
                           callback.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(callback);
    ASSERT_EQ(PP_OK, callback.result());
    rv = file_ref_abort.Delete(callback.GetCallback());
  }
  callback.WaitForAbortResult(rv);
  CHECK_CALLBACK_BEHAVIOR(callback);

  PASS();
}

std::string TestFileRef::TestRenameFileAndDirectory() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileRef file_ref(file_system, "/file_rename");
  pp::FileIO file_io(instance_);
  callback.WaitForResult(
      file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileRef target_file_ref(file_system, "/target_file_rename");
  callback.WaitForResult(
      file_ref.Rename(target_file_ref, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileRef dir_ref(file_system, "/dir_rename");
  callback.WaitForResult(dir_ref.MakeDirectory(
      PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileRef target_dir_ref(file_system, "/target_dir_rename");
  callback.WaitForResult(
      dir_ref.Rename(target_dir_ref, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileRef nested_dir_ref(file_system, "/dir_rename_1/dir_rename_2");
  callback.WaitForResult(
      nested_dir_ref.MakeDirectory(PP_MAKEDIRECTORYFLAG_WITH_ANCESTORS,
                                   callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Try to rename nested directory to the parent name. Should fail.
  pp::FileRef target_nested_dir_ref(file_system, "/dir_rename_1");
  callback.WaitForResult(
      nested_dir_ref.Rename(target_nested_dir_ref, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_ERROR_FAILED, callback.result());

  // Rename aborted.
  // TODO(viettrungluu): Figure out what we want to do if the target file
  // resource is destroyed before completion.
  int32_t rv = PP_ERROR_FAILED;
  pp::FileRef target_file_ref_abort(file_system,
                                    "/target_file_rename_abort");
  {
    pp::FileRef file_ref_abort(file_system, "/file_rename_abort");
    pp::FileIO file_io_abort(instance_);
    callback.WaitForResult(
        file_io_abort.Open(file_ref_abort, PP_FILEOPENFLAG_CREATE,
                           callback.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(callback);
    ASSERT_EQ(PP_OK, callback.result());

    rv = file_ref_abort.Rename(target_file_ref_abort, callback.GetCallback());
  }
  callback.WaitForAbortResult(rv);
  CHECK_CALLBACK_BEHAVIOR(callback);

  PASS();
}

std::string TestFileRef::TestQuery() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());

  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  pp::FileRef file_ref(file_system, "/file");
  pp::FileIO file_io(instance_);
  callback.WaitForResult(file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE,
                                      callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // We touch the file so we can easily check access and modified time.
  callback.WaitForResult(file_io.Touch(0, 0, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  TestCompletionCallbackWithOutput<PP_FileInfo> out_callback(
      instance_->pp_instance(), callback_type());
  out_callback.WaitForResult(file_ref.Query(out_callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(out_callback);
  ASSERT_EQ(PP_OK, out_callback.result());

  PP_FileInfo info = out_callback.output();
  ASSERT_EQ(0, info.size);
  ASSERT_EQ(PP_FILETYPE_REGULAR, info.type);
  ASSERT_EQ(PP_FILESYSTEMTYPE_LOCALTEMPORARY, info.system_type);
  ASSERT_DOUBLE_EQ(0.0, info.last_access_time);
  ASSERT_DOUBLE_EQ(0.0, info.last_modified_time);

  // Query a file ref on an external filesystem.
  pp::FileRef file_ref_ext;
  std::string result = MakeExternalFileRef(&file_ref_ext);
  if (!result.empty())
    return result;
  out_callback.WaitForResult(file_ref_ext.Query(out_callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(out_callback);
  if (out_callback.result() != PP_OK)
    return ReportError("Query() result", out_callback.result());
  ASSERT_EQ(PP_OK, out_callback.result());

  info = out_callback.output();
  ASSERT_EQ(PP_FILETYPE_REGULAR, info.type);
  ASSERT_EQ(PP_FILESYSTEMTYPE_EXTERNAL, info.system_type);

  // We can't touch the file, so just sanity check the times.
  ASSERT_TRUE(info.creation_time >= 0.0);
  ASSERT_TRUE(info.last_modified_time >= 0.0);
  ASSERT_TRUE(info.last_access_time >= 0.0);

  // Query a file ref for a file that doesn't exist.
  pp::FileRef missing_file_ref(file_system, "/missing_file");
  out_callback.WaitForResult(missing_file_ref.Query(
      out_callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(out_callback);
  ASSERT_EQ(PP_ERROR_FILENOTFOUND, out_callback.result());

  PASS();
}

std::string TestFileRef::TestFileNameEscaping() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  pp::FileSystem file_system(instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  std::string test_dir_path = "/dir_for_escaping_test";
  // Create a directory in which to test.
  pp::FileRef test_dir_ref(file_system, test_dir_path.c_str());
  callback.WaitForResult(test_dir_ref.MakeDirectory(
      PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Create the file with the terrible name.
  std::string full_file_path = test_dir_path + "/" + kTerribleName;
  pp::FileRef file_ref(file_system, full_file_path.c_str());
  pp::FileIO file_io(instance_);
  callback.WaitForResult(
      file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // FileRef::ReadDirectoryEntries only works out-of-process.
  if (testing_interface_->IsOutOfProcess()) {
    TestCompletionCallbackWithOutput<DirEntries>
        output_callback(instance_->pp_instance(), callback_type());

    output_callback.WaitForResult(
        test_dir_ref.ReadDirectoryEntries(output_callback.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(output_callback);
    ASSERT_EQ(PP_OK, output_callback.result());

    DirEntries entries = output_callback.output();
    ASSERT_EQ(1, entries.size());
    ASSERT_EQ(kTerribleName, entries.front().file_ref().GetName().AsString());
  }

  PASS();
}

std::string TestFileRef::TestReadDirectoryEntries() {
  TestCompletionCallback callback(instance_->pp_instance(), callback_type());
  pp::FileSystem file_system(
      instance_, PP_FILESYSTEMTYPE_LOCALTEMPORARY);
  callback.WaitForResult(file_system.Open(1024, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  // Setup testing directories and files.
  const char* test_dir_name = "/test_get_next_file";
  const char* file_prefix = "file_";
  const char* dir_prefix = "dir_";

  pp::FileRef test_dir(file_system, test_dir_name);
  int32_t rv = DeleteDirectoryRecursively(&test_dir);
  ASSERT_TRUE(rv == PP_OK || rv == PP_ERROR_FILENOTFOUND);

  callback.WaitForResult(test_dir.MakeDirectory(
      PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
  CHECK_CALLBACK_BEHAVIOR(callback);
  ASSERT_EQ(PP_OK, callback.result());

  static const int kNumFiles = 3;
  std::set<std::string> expected_file_names;
  for (int i = 1; i <= kNumFiles; ++i) {
    std::ostringstream buffer;
    buffer << test_dir_name << '/' << file_prefix << i;
    pp::FileRef file_ref(file_system, buffer.str().c_str());

    pp::FileIO file_io(instance_);
    callback.WaitForResult(
        file_io.Open(file_ref, PP_FILEOPENFLAG_CREATE, callback.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(callback);
    ASSERT_EQ(PP_OK, callback.result());

    expected_file_names.insert(buffer.str());
  }

  static const int kNumDirectories = 3;
  std::set<std::string> expected_dir_names;
  for (int i = 1; i <= kNumDirectories; ++i) {
    std::ostringstream buffer;
    buffer << test_dir_name << '/' << dir_prefix << i;
    pp::FileRef file_ref(file_system, buffer.str().c_str());

    callback.WaitForResult(file_ref.MakeDirectory(
        PP_MAKEDIRECTORYFLAG_NONE, callback.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(callback);
    ASSERT_EQ(PP_OK, callback.result());

    expected_dir_names.insert(buffer.str());
  }

  // Test that |ReadDirectoryEntries()| is able to fetch all
  // directories and files that we created.
  {
    TestCompletionCallbackWithOutput<DirEntries> output_callback(
        instance_->pp_instance(), callback_type());

    output_callback.WaitForResult(
        test_dir.ReadDirectoryEntries(output_callback.GetCallback()));
    CHECK_CALLBACK_BEHAVIOR(output_callback);
    ASSERT_EQ(PP_OK, output_callback.result());

    DirEntries entries = output_callback.output();
    size_t sum = expected_file_names.size() + expected_dir_names.size();
    ASSERT_EQ(sum, entries.size());

    for (DirEntries::const_iterator it = entries.begin();
         it != entries.end(); ++it) {
      pp::FileRef file_ref = it->file_ref();
      std::string file_path = file_ref.GetPath().AsString();
      std::set<std::string>::iterator found =
          expected_file_names.find(file_path);
      if (found != expected_file_names.end()) {
        if (it->file_type() != PP_FILETYPE_REGULAR)
          return file_path + " should have been a regular file.";
        expected_file_names.erase(found);
      } else {
        found = expected_dir_names.find(file_path);
        if (found == expected_dir_names.end())
          return "Unexpected file path: " + file_path;
        if (it->file_type() != PP_FILETYPE_DIRECTORY)
          return file_path + " should have been a directory.";
        expected_dir_names.erase(found);
      }
    }
    ASSERT_TRUE(expected_file_names.empty());
    ASSERT_TRUE(expected_dir_names.empty());
  }

  // Test cancellation of asynchronous |ReadDirectoryEntries()|.
  TestCompletionCallbackWithOutput<DirEntries> output_callback(
      instance_->pp_instance(), callback_type());
  {
    rv = pp::FileRef(file_system, test_dir_name)
        .ReadDirectoryEntries(output_callback.GetCallback());
  }
  output_callback.WaitForAbortResult(rv);
  CHECK_CALLBACK_BEHAVIOR(output_callback);


  PASS();
}
