// Copyright 2013 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/basictypes.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "content/public/test/async_file_test_helper.h"
#include "content/public/test/mock_special_storage_policy.h"
#include "content/public/test/test_file_system_backend.h"
#include "content/public/test/test_file_system_context.h"
#include "storage/browser/blob/shareable_file_reference.h"
#include "storage/browser/fileapi/copy_or_move_file_validator.h"
#include "storage/browser/fileapi/external_mount_points.h"
#include "storage/browser/fileapi/file_system_backend.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/browser/fileapi/isolated_context.h"
#include "storage/common/fileapi/file_system_util.h"
#include "testing/gtest/include/gtest/gtest.h"

using content::AsyncFileTestHelper;
using storage::CopyOrMoveFileValidator;
using storage::CopyOrMoveFileValidatorFactory;
using storage::FileSystemURL;

namespace content {

namespace {

const storage::FileSystemType kNoValidatorType =
    storage::kFileSystemTypeTemporary;
const storage::FileSystemType kWithValidatorType = storage::kFileSystemTypeTest;

void ExpectOk(const GURL& origin_url,
              const std::string& name,
              base::File::Error error) {
  ASSERT_EQ(base::File::FILE_OK, error);
}

class CopyOrMoveFileValidatorTestHelper {
 public:
  CopyOrMoveFileValidatorTestHelper(const GURL& origin,
                                    storage::FileSystemType src_type,
                                    storage::FileSystemType dest_type)
      : origin_(origin), src_type_(src_type), dest_type_(dest_type) {}

  ~CopyOrMoveFileValidatorTestHelper() {
    file_system_context_ = NULL;
    base::RunLoop().RunUntilIdle();
  }

  void SetUp() {
    ASSERT_TRUE(base_.CreateUniqueTempDir());
    base::FilePath base_dir = base_.path();

    file_system_context_ = CreateFileSystemContextForTesting(NULL, base_dir);

    // Set up TestFileSystemBackend to require CopyOrMoveFileValidator.
    storage::FileSystemBackend* test_file_system_backend =
        file_system_context_->GetFileSystemBackend(kWithValidatorType);
    static_cast<TestFileSystemBackend*>(test_file_system_backend)->
        set_require_copy_or_move_validator(true);

    // Sets up source.
    storage::FileSystemBackend* src_file_system_backend =
        file_system_context_->GetFileSystemBackend(src_type_);
    src_file_system_backend->ResolveURL(
        FileSystemURL::CreateForTest(origin_, src_type_, base::FilePath()),
        storage::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT,
        base::Bind(&ExpectOk));
    base::RunLoop().RunUntilIdle();
    ASSERT_EQ(base::File::FILE_OK, CreateDirectory(SourceURL("")));

    // Sets up dest.
    DCHECK_EQ(kWithValidatorType, dest_type_);
    ASSERT_EQ(base::File::FILE_OK, CreateDirectory(DestURL("")));

    copy_src_ = SourceURL("copy_src.jpg");
    move_src_ = SourceURL("move_src.jpg");
    copy_dest_ = DestURL("copy_dest.jpg");
    move_dest_ = DestURL("move_dest.jpg");

    ASSERT_EQ(base::File::FILE_OK, CreateFile(copy_src_, 10));
    ASSERT_EQ(base::File::FILE_OK, CreateFile(move_src_, 10));

    ASSERT_TRUE(FileExists(copy_src_, 10));
    ASSERT_TRUE(FileExists(move_src_, 10));
    ASSERT_FALSE(FileExists(copy_dest_, 10));
    ASSERT_FALSE(FileExists(move_dest_, 10));
  }

  void SetMediaCopyOrMoveFileValidatorFactory(
      scoped_ptr<storage::CopyOrMoveFileValidatorFactory> factory) {
    TestFileSystemBackend* backend = static_cast<TestFileSystemBackend*>(
        file_system_context_->GetFileSystemBackend(kWithValidatorType));
    backend->InitializeCopyOrMoveFileValidatorFactory(factory.Pass());
  }

  void CopyTest(base::File::Error expected) {
    ASSERT_TRUE(FileExists(copy_src_, 10));
    ASSERT_FALSE(FileExists(copy_dest_, 10));

    EXPECT_EQ(expected,
              AsyncFileTestHelper::Copy(
                  file_system_context_.get(), copy_src_, copy_dest_));

    EXPECT_TRUE(FileExists(copy_src_, 10));
    if (expected == base::File::FILE_OK)
      EXPECT_TRUE(FileExists(copy_dest_, 10));
    else
      EXPECT_FALSE(FileExists(copy_dest_, 10));
  };

  void MoveTest(base::File::Error expected) {
    ASSERT_TRUE(FileExists(move_src_, 10));
    ASSERT_FALSE(FileExists(move_dest_, 10));

    EXPECT_EQ(expected,
              AsyncFileTestHelper::Move(
                  file_system_context_.get(), move_src_, move_dest_));

    if (expected == base::File::FILE_OK) {
      EXPECT_FALSE(FileExists(move_src_, 10));
      EXPECT_TRUE(FileExists(move_dest_, 10));
    } else {
      EXPECT_TRUE(FileExists(move_src_, 10));
      EXPECT_FALSE(FileExists(move_dest_, 10));
    }
  };

 private:
  FileSystemURL SourceURL(const std::string& path) {
    return file_system_context_->CreateCrackedFileSystemURL(
        origin_, src_type_,
        base::FilePath().AppendASCII("src").AppendASCII(path));
  }

  FileSystemURL DestURL(const std::string& path) {
    return file_system_context_->CreateCrackedFileSystemURL(
        origin_, dest_type_,
        base::FilePath().AppendASCII("dest").AppendASCII(path));
  }

  base::File::Error CreateFile(const FileSystemURL& url, size_t size) {
    base::File::Error result =
        AsyncFileTestHelper::CreateFile(file_system_context_.get(), url);
    if (result != base::File::FILE_OK)
      return result;
    return AsyncFileTestHelper::TruncateFile(
        file_system_context_.get(), url, size);
  }

  base::File::Error CreateDirectory(const FileSystemURL& url) {
    return AsyncFileTestHelper::CreateDirectory(file_system_context_.get(),
                                                url);
  }

  bool FileExists(const FileSystemURL& url, int64 expected_size) {
    return AsyncFileTestHelper::FileExists(
        file_system_context_.get(), url, expected_size);
  }

  base::ScopedTempDir base_;

  const GURL origin_;

  const storage::FileSystemType src_type_;
  const storage::FileSystemType dest_type_;
  std::string src_fsid_;
  std::string dest_fsid_;

  base::MessageLoop message_loop_;
  scoped_refptr<storage::FileSystemContext> file_system_context_;

  FileSystemURL copy_src_;
  FileSystemURL copy_dest_;
  FileSystemURL move_src_;
  FileSystemURL move_dest_;

  DISALLOW_COPY_AND_ASSIGN(CopyOrMoveFileValidatorTestHelper);
};

// For TestCopyOrMoveFileValidatorFactory
enum Validity {
  VALID,
  PRE_WRITE_INVALID,
  POST_WRITE_INVALID
};

class TestCopyOrMoveFileValidatorFactory
    : public storage::CopyOrMoveFileValidatorFactory {
 public:
  // A factory that creates validators that accept everything or nothing.
  // TODO(gbillock): switch args to enum or something
  explicit TestCopyOrMoveFileValidatorFactory(Validity validity)
      : validity_(validity) {}
  ~TestCopyOrMoveFileValidatorFactory() override {}

  storage::CopyOrMoveFileValidator* CreateCopyOrMoveFileValidator(
      const FileSystemURL& /*src_url*/,
      const base::FilePath& /*platform_path*/) override {
    return new TestCopyOrMoveFileValidator(validity_);
  }

 private:
  class TestCopyOrMoveFileValidator : public CopyOrMoveFileValidator {
   public:
    explicit TestCopyOrMoveFileValidator(Validity validity)
        : result_(validity == VALID || validity == POST_WRITE_INVALID ?
                  base::File::FILE_OK :
                  base::File::FILE_ERROR_SECURITY),
          write_result_(validity == VALID || validity == PRE_WRITE_INVALID ?
                        base::File::FILE_OK :
                        base::File::FILE_ERROR_SECURITY) {
    }
    ~TestCopyOrMoveFileValidator() override {}

    void StartPreWriteValidation(
        const ResultCallback& result_callback) override {
      // Post the result since a real validator must do work asynchronously.
      base::MessageLoop::current()->PostTask(
          FROM_HERE, base::Bind(result_callback, result_));
    }

    void StartPostWriteValidation(
        const base::FilePath& dest_platform_path,
        const ResultCallback& result_callback) override {
      // Post the result since a real validator must do work asynchronously.
      base::MessageLoop::current()->PostTask(
          FROM_HERE, base::Bind(result_callback, write_result_));
    }

   private:
    base::File::Error result_;
    base::File::Error write_result_;

    DISALLOW_COPY_AND_ASSIGN(TestCopyOrMoveFileValidator);
  };

  Validity validity_;

  DISALLOW_COPY_AND_ASSIGN(TestCopyOrMoveFileValidatorFactory);
};

}  // namespace

TEST(CopyOrMoveFileValidatorTest, NoValidatorWithinSameFSType) {
  // Within a file system type, validation is not expected, so it should
  // work for kWithValidatorType without a validator set.
  CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
                                           kWithValidatorType,
                                           kWithValidatorType);
  helper.SetUp();
  helper.CopyTest(base::File::FILE_OK);
  helper.MoveTest(base::File::FILE_OK);
}

TEST(CopyOrMoveFileValidatorTest, MissingValidator) {
  // Copying or moving into a kWithValidatorType requires a file
  // validator.  An error is expected if copy is attempted without a validator.
  CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
                                           kNoValidatorType,
                                           kWithValidatorType);
  helper.SetUp();
  helper.CopyTest(base::File::FILE_ERROR_SECURITY);
  helper.MoveTest(base::File::FILE_ERROR_SECURITY);
}

TEST(CopyOrMoveFileValidatorTest, AcceptAll) {
  CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
                                           kNoValidatorType,
                                           kWithValidatorType);
  helper.SetUp();
  scoped_ptr<CopyOrMoveFileValidatorFactory> factory(
      new TestCopyOrMoveFileValidatorFactory(VALID));
  helper.SetMediaCopyOrMoveFileValidatorFactory(factory.Pass());

  helper.CopyTest(base::File::FILE_OK);
  helper.MoveTest(base::File::FILE_OK);
}

TEST(CopyOrMoveFileValidatorTest, AcceptNone) {
  CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
                                           kNoValidatorType,
                                           kWithValidatorType);
  helper.SetUp();
  scoped_ptr<CopyOrMoveFileValidatorFactory> factory(
      new TestCopyOrMoveFileValidatorFactory(PRE_WRITE_INVALID));
  helper.SetMediaCopyOrMoveFileValidatorFactory(factory.Pass());

  helper.CopyTest(base::File::FILE_ERROR_SECURITY);
  helper.MoveTest(base::File::FILE_ERROR_SECURITY);
}

TEST(CopyOrMoveFileValidatorTest, OverrideValidator) {
  // Once set, you can not override the validator.
  CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
                                           kNoValidatorType,
                                           kWithValidatorType);
  helper.SetUp();
  scoped_ptr<CopyOrMoveFileValidatorFactory> reject_factory(
      new TestCopyOrMoveFileValidatorFactory(PRE_WRITE_INVALID));
  helper.SetMediaCopyOrMoveFileValidatorFactory(reject_factory.Pass());

  scoped_ptr<CopyOrMoveFileValidatorFactory> accept_factory(
      new TestCopyOrMoveFileValidatorFactory(VALID));
  helper.SetMediaCopyOrMoveFileValidatorFactory(accept_factory.Pass());

  helper.CopyTest(base::File::FILE_ERROR_SECURITY);
  helper.MoveTest(base::File::FILE_ERROR_SECURITY);
}

TEST(CopyOrMoveFileValidatorTest, RejectPostWrite) {
  CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
                                           kNoValidatorType,
                                           kWithValidatorType);
  helper.SetUp();
  scoped_ptr<CopyOrMoveFileValidatorFactory> factory(
      new TestCopyOrMoveFileValidatorFactory(POST_WRITE_INVALID));
  helper.SetMediaCopyOrMoveFileValidatorFactory(factory.Pass());

  helper.CopyTest(base::File::FILE_ERROR_SECURITY);
  helper.MoveTest(base::File::FILE_ERROR_SECURITY);
}

}  // namespace content
