// 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 <set>
#include <string>
#include <vector>

#include "base/bind_helpers.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/run_loop.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
#include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
#include "chrome/browser/media_galleries/fileapi/picasa_data_provider.h"
#include "chrome/browser/media_galleries/fileapi/picasa_file_util.h"
#include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
#include "chrome/common/media_galleries/picasa_types.h"
#include "chrome/common/media_galleries/pmp_constants.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/mock_special_storage_policy.h"
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_file_system_options.h"
#include "storage/browser/blob/shareable_file_reference.h"
#include "storage/browser/fileapi/async_file_util.h"
#include "storage/browser/fileapi/external_mount_points.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_operation_context.h"
#include "storage/browser/fileapi/file_system_operation_runner.h"
#include "storage/browser/fileapi/isolated_context.h"
#include "testing/gtest/include/gtest/gtest.h"

using storage::FileSystemOperationContext;
using storage::FileSystemOperation;
using storage::FileSystemURL;

namespace picasa {

namespace {

base::Time::Exploded test_date_exploded = { 2013, 4, 0, 16, 0, 0, 0, 0 };

bool WriteJPEGHeader(const base::FilePath& path) {
  const char kJpegHeader[] = "\xFF\xD8\xFF";  // Per HTML5 specification.
  return base::WriteFile(path, kJpegHeader, arraysize(kJpegHeader)) != -1;
}

class TestFolder {
 public:
  TestFolder(const std::string& name, const base::Time& timestamp,
             const std::string& uid, unsigned int image_files,
             unsigned int non_image_files)
      : name_(name),
        timestamp_(timestamp),
        uid_(uid),
        image_files_(image_files),
        non_image_files_(non_image_files),
        folder_info_("", base::Time(), "", base::FilePath()) {
  }

  bool Init() {
    if (!folder_dir_.CreateUniqueTempDir())
      return false;

    folder_info_ = AlbumInfo(name_, timestamp_, uid_, folder_dir_.path());

    for (unsigned int i = 0; i < image_files_; ++i) {
      std::string image_filename = base::StringPrintf("img%05d.jpg", i);
      image_filenames_.insert(image_filename);

      base::FilePath path = folder_dir_.path().AppendASCII(image_filename);

      if (!WriteJPEGHeader(path))
        return false;
    }

    for (unsigned int i = 0; i < non_image_files_; ++i) {
      base::FilePath path = folder_dir_.path().AppendASCII(
          base::StringPrintf("hello%05d.txt", i));
      if (base::WriteFile(path, NULL, 0) == -1)
        return false;
    }

    return true;
  }

  double GetVariantTimestamp() const {
    DCHECK(!folder_dir_.path().empty());
    base::Time variant_epoch = base::Time::FromLocalExploded(
        picasa::kPmpVariantTimeEpoch);

    int64 microseconds_since_epoch =
        (folder_info_.timestamp - variant_epoch).InMicroseconds();

    return static_cast<double>(microseconds_since_epoch) /
                               base::Time::kMicrosecondsPerDay;
  }

  const std::set<std::string>& image_filenames() const {
    DCHECK(!folder_dir_.path().empty());
    return image_filenames_;
  }

  const AlbumInfo& folder_info() const {
    DCHECK(!folder_dir_.path().empty());
    return folder_info_;
  }

  const base::Time& timestamp() const {
    return timestamp_;
  }

 private:
  const std::string name_;
  const base::Time timestamp_;
  const std::string uid_;
  unsigned int image_files_;
  unsigned int non_image_files_;

  std::set<std::string> image_filenames_;

  base::ScopedTempDir folder_dir_;
  AlbumInfo folder_info_;
};

void ReadDirectoryTestHelperCallback(
    base::RunLoop* run_loop,
    FileSystemOperation::FileEntryList* contents,
    bool* completed, base::File::Error error,
    const FileSystemOperation::FileEntryList& file_list,
    bool has_more) {
  DCHECK(!*completed);
  *completed = !has_more && error == base::File::FILE_OK;
  *contents = file_list;
  run_loop->Quit();
}

void ReadDirectoryTestHelper(storage::FileSystemOperationRunner* runner,
                             const FileSystemURL& url,
                             FileSystemOperation::FileEntryList* contents,
                             bool* completed) {
  DCHECK(contents);
  DCHECK(completed);
  base::RunLoop run_loop;
  runner->ReadDirectory(
      url, base::Bind(&ReadDirectoryTestHelperCallback, &run_loop, contents,
                      completed));
  run_loop.Run();
}

void SynchronouslyRunOnMediaTaskRunner(const base::Closure& closure) {
  base::RunLoop loop;
  MediaFileSystemBackend::MediaTaskRunner()->PostTaskAndReply(
      FROM_HERE,
      closure,
      loop.QuitClosure());
  loop.Run();
}

void CreateSnapshotFileTestHelperCallback(
    base::RunLoop* run_loop,
    base::File::Error* error,
    base::FilePath* platform_path_result,
    base::File::Error result,
    const base::File::Info& file_info,
    const base::FilePath& platform_path,
    const scoped_refptr<storage::ShareableFileReference>& file_ref) {
  DCHECK(run_loop);
  DCHECK(error);
  DCHECK(platform_path_result);

  *error = result;
  *platform_path_result = platform_path;
  run_loop->Quit();
}

}  // namespace

class TestPicasaFileUtil : public PicasaFileUtil {
 public:
  TestPicasaFileUtil(MediaPathFilter* media_path_filter,
                     PicasaDataProvider* data_provider)
      : PicasaFileUtil(media_path_filter),
        data_provider_(data_provider) {
  }
  ~TestPicasaFileUtil() override {}

 private:
  PicasaDataProvider* GetDataProvider() override { return data_provider_; }

  PicasaDataProvider* data_provider_;
};

class TestMediaFileSystemBackend : public MediaFileSystemBackend {
 public:
  TestMediaFileSystemBackend(const base::FilePath& profile_path,
                             PicasaFileUtil* picasa_file_util)
      : MediaFileSystemBackend(profile_path,
                               MediaFileSystemBackend::MediaTaskRunner().get()),
        test_file_util_(picasa_file_util) {}

  storage::AsyncFileUtil* GetAsyncFileUtil(
      storage::FileSystemType type) override {
    if (type != storage::kFileSystemTypePicasa)
      return NULL;

    return test_file_util_.get();
  }

 private:
  scoped_ptr<storage::AsyncFileUtil> test_file_util_;
};

class PicasaFileUtilTest : public testing::Test {
 public:
  PicasaFileUtilTest()
      : io_thread_(content::BrowserThread::IO, &message_loop_) {
  }

  void SetUp() override {
    ASSERT_TRUE(profile_dir_.CreateUniqueTempDir());
    ImportedMediaGalleryRegistry::GetInstance()->Initialize();

    scoped_refptr<storage::SpecialStoragePolicy> storage_policy =
        new content::MockSpecialStoragePolicy();

    SynchronouslyRunOnMediaTaskRunner(base::Bind(
        &PicasaFileUtilTest::SetUpOnMediaTaskRunner, base::Unretained(this)));

    media_path_filter_.reset(new MediaPathFilter());

    ScopedVector<storage::FileSystemBackend> additional_providers;
    additional_providers.push_back(new TestMediaFileSystemBackend(
        profile_dir_.path(),
        new TestPicasaFileUtil(media_path_filter_.get(),
                               picasa_data_provider_.get())));

    file_system_context_ = new storage::FileSystemContext(
        base::MessageLoopProxy::current().get(),
        base::MessageLoopProxy::current().get(),
        storage::ExternalMountPoints::CreateRefCounted().get(),
        storage_policy.get(),
        NULL,
        additional_providers.Pass(),
        std::vector<storage::URLRequestAutoMountHandler>(),
        profile_dir_.path(),
        content::CreateAllowFileAccessOptions());
  }

  void TearDown() override {
    SynchronouslyRunOnMediaTaskRunner(
        base::Bind(&PicasaFileUtilTest::TearDownOnMediaTaskRunner,
                   base::Unretained(this)));
  }

 protected:
  void SetUpOnMediaTaskRunner() {
    picasa_data_provider_.reset(new PicasaDataProvider(base::FilePath()));
  }

  void TearDownOnMediaTaskRunner() {
    picasa_data_provider_.reset();
  }

  // |test_folders| must be in alphabetical order for easy verification
  void SetupFolders(ScopedVector<TestFolder>* test_folders,
                    const std::vector<AlbumInfo>& albums,
                    const AlbumImagesMap& albums_images) {
    std::vector<AlbumInfo> folders;
    for (ScopedVector<TestFolder>::iterator it = test_folders->begin();
        it != test_folders->end(); ++it) {
      TestFolder* test_folder = *it;
      ASSERT_TRUE(test_folder->Init());
      folders.push_back(test_folder->folder_info());
    }

    PicasaDataProvider::UniquifyNames(albums,
                                      &picasa_data_provider_->album_map_);
    PicasaDataProvider::UniquifyNames(folders,
                                      &picasa_data_provider_->folder_map_);
    picasa_data_provider_->albums_images_ = albums_images;
    picasa_data_provider_->state_ =
        PicasaDataProvider::ALBUMS_IMAGES_FRESH_STATE;
  }

  void VerifyFolderDirectoryList(const ScopedVector<TestFolder>& test_folders) {
    FileSystemOperation::FileEntryList contents;
    FileSystemURL url = CreateURL(kPicasaDirFolders);
    bool completed = false;
    ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);

    ASSERT_TRUE(completed);
    ASSERT_EQ(test_folders.size(), contents.size());

    for (size_t i = 0; i < contents.size(); ++i) {
      EXPECT_TRUE(contents[i].is_directory);

      // Because the timestamp is written out as a floating point Microsoft
      // variant time, we only expect it to be accurate to within a second.
      base::TimeDelta delta = test_folders[i]->folder_info().timestamp -
                              contents[i].last_modified_time;
      EXPECT_LT(delta, base::TimeDelta::FromSeconds(1));

      FileSystemOperation::FileEntryList folder_contents;
      FileSystemURL folder_url = CreateURL(
          std::string(kPicasaDirFolders) + "/" +
          base::FilePath(contents[i].name).AsUTF8Unsafe());
      bool folder_read_completed = false;
      ReadDirectoryTestHelper(operation_runner(), folder_url, &folder_contents,
                              &folder_read_completed);

      EXPECT_TRUE(folder_read_completed);

      const std::set<std::string>& image_filenames =
          test_folders[i]->image_filenames();

      EXPECT_EQ(image_filenames.size(), folder_contents.size());

      for (FileSystemOperation::FileEntryList::const_iterator file_it =
               folder_contents.begin(); file_it != folder_contents.end();
           ++file_it) {
        EXPECT_EQ(1u, image_filenames.count(
            base::FilePath(file_it->name).AsUTF8Unsafe()));
      }
    }
  }

  std::string DateToPathString(const base::Time& time) {
    return PicasaDataProvider::DateToPathString(time);
  }

  void TestNonexistentDirectory(const std::string& path) {
    FileSystemOperation::FileEntryList contents;
    FileSystemURL url = CreateURL(path);
    bool completed = false;
    ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);

    ASSERT_FALSE(completed);
  }

  void TestEmptyDirectory(const std::string& path) {
    FileSystemOperation::FileEntryList contents;
    FileSystemURL url = CreateURL(path);
    bool completed = false;
    ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);

    ASSERT_TRUE(completed);
    EXPECT_EQ(0u, contents.size());
  }

  FileSystemURL CreateURL(const std::string& path) const {
    base::FilePath virtual_path =
        ImportedMediaGalleryRegistry::GetInstance()->ImportedRoot();
    virtual_path = virtual_path.AppendASCII("picasa");
    virtual_path = virtual_path.AppendASCII(path);
    return file_system_context_->CreateCrackedFileSystemURL(
        GURL("http://www.example.com"),
        storage::kFileSystemTypePicasa,
        virtual_path);
  }

  storage::FileSystemOperationRunner* operation_runner() const {
    return file_system_context_->operation_runner();
  }

  scoped_refptr<storage::FileSystemContext> file_system_context() const {
    return file_system_context_;
  }

 private:
  base::MessageLoop message_loop_;
  content::TestBrowserThread io_thread_;

  base::ScopedTempDir profile_dir_;

  scoped_refptr<storage::FileSystemContext> file_system_context_;
  scoped_ptr<PicasaDataProvider> picasa_data_provider_;
  scoped_ptr<MediaPathFilter> media_path_filter_;

  DISALLOW_COPY_AND_ASSIGN(PicasaFileUtilTest);
};

TEST_F(PicasaFileUtilTest, DateFormat) {
  base::Time::Exploded exploded_shortmonth = { 2013, 4, 0, 16, 0, 0, 0, 0 };
  base::Time shortmonth = base::Time::FromLocalExploded(exploded_shortmonth);

  base::Time::Exploded exploded_shortday = { 2013, 11, 0, 3, 0, 0, 0, 0 };
  base::Time shortday = base::Time::FromLocalExploded(exploded_shortday);

  EXPECT_EQ("2013-04-16", DateToPathString(shortmonth));
  EXPECT_EQ("2013-11-03", DateToPathString(shortday));
}

TEST_F(PicasaFileUtilTest, NameDeduplication) {
  ScopedVector<TestFolder> test_folders;
  std::vector<std::string> expected_names;

  base::Time test_date = base::Time::FromLocalExploded(test_date_exploded);
  base::Time test_date_2 = test_date - base::TimeDelta::FromDays(1);

  std::string test_date_string = DateToPathString(test_date);
  std::string test_date_2_string = DateToPathString(test_date_2);

  test_folders.push_back(
      new TestFolder("diff_date", test_date_2, "uuid3", 0, 0));
  expected_names.push_back("diff_date " + test_date_2_string);

  test_folders.push_back(
      new TestFolder("diff_date", test_date, "uuid2", 0, 0));
  expected_names.push_back("diff_date " + test_date_string);

  test_folders.push_back(
      new TestFolder("duplicate", test_date, "uuid4", 0, 0));
  expected_names.push_back("duplicate " + test_date_string + " (1)");

  test_folders.push_back(
      new TestFolder("duplicate", test_date, "uuid5", 0, 0));
  expected_names.push_back("duplicate " + test_date_string + " (2)");

  test_folders.push_back(
      new TestFolder("unique_name", test_date, "uuid1", 0, 0));
  expected_names.push_back("unique_name " + test_date_string);

  SetupFolders(&test_folders, std::vector<AlbumInfo>(), AlbumImagesMap());

  FileSystemOperation::FileEntryList contents;
  FileSystemURL url = CreateURL(kPicasaDirFolders);
  bool completed = false;
  ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);

  ASSERT_TRUE(completed);
  ASSERT_EQ(expected_names.size(), contents.size());
  for (size_t i = 0; i < contents.size(); ++i) {
    EXPECT_EQ(expected_names[i],
              base::FilePath(contents[i].name).AsUTF8Unsafe());
    EXPECT_EQ(test_folders[i]->timestamp(), contents[i].last_modified_time);
    EXPECT_TRUE(contents[i].is_directory);
  }
}

TEST_F(PicasaFileUtilTest, RootFolders) {
  ScopedVector<TestFolder> empty_folders_list;
  SetupFolders(&empty_folders_list, std::vector<AlbumInfo>(), AlbumImagesMap());

  FileSystemOperation::FileEntryList contents;
  FileSystemURL url = CreateURL("");
  bool completed = false;
  ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);

  ASSERT_TRUE(completed);
  ASSERT_EQ(2u, contents.size());

  EXPECT_TRUE(contents.front().is_directory);
  EXPECT_TRUE(contents.back().is_directory);

  EXPECT_EQ(0, contents.front().size);
  EXPECT_EQ(0, contents.back().size);

  EXPECT_EQ(FILE_PATH_LITERAL("albums"), contents.front().name);
  EXPECT_EQ(FILE_PATH_LITERAL("folders"), contents.back().name);
}

TEST_F(PicasaFileUtilTest, NonexistentFolder) {
  ScopedVector<TestFolder> empty_folders_list;
  SetupFolders(&empty_folders_list, std::vector<AlbumInfo>(), AlbumImagesMap());

  TestNonexistentDirectory(std::string(kPicasaDirFolders) + "/foo");
  TestNonexistentDirectory(std::string(kPicasaDirFolders) + "/foo/bar");
  TestNonexistentDirectory(std::string(kPicasaDirFolders) + "/foo/bar/baz");
}

TEST_F(PicasaFileUtilTest, FolderContentsTrivial) {
  ScopedVector<TestFolder> test_folders;
  base::Time test_date = base::Time::FromLocalExploded(test_date_exploded);

  test_folders.push_back(
      new TestFolder("folder-1-empty", test_date, "uid-empty", 0, 0));
  test_folders.push_back(
      new TestFolder("folder-2-images", test_date, "uid-images", 5, 0));
  test_folders.push_back(
      new TestFolder("folder-3-nonimages", test_date, "uid-nonimages", 0, 5));
  test_folders.push_back(
      new TestFolder("folder-4-both", test_date, "uid-both", 5, 5));

  SetupFolders(&test_folders, std::vector<AlbumInfo>(), AlbumImagesMap());
  VerifyFolderDirectoryList(test_folders);
}

TEST_F(PicasaFileUtilTest, FolderWithManyFiles) {
  ScopedVector<TestFolder> test_folders;
  base::Time test_date = base::Time::FromLocalExploded(test_date_exploded);

  test_folders.push_back(
      new TestFolder("folder-many-files", test_date, "uid-both", 50, 50));

  SetupFolders(&test_folders, std::vector<AlbumInfo>(), AlbumImagesMap());
  VerifyFolderDirectoryList(test_folders);
}

TEST_F(PicasaFileUtilTest, ManyFolders) {
  ScopedVector<TestFolder> test_folders;
  base::Time test_date = base::Time::FromLocalExploded(test_date_exploded);

  for (unsigned int i = 0; i < 50; ++i) {
    base::Time date = test_date - base::TimeDelta::FromDays(i);

    test_folders.push_back(
        new TestFolder(base::StringPrintf("folder-%05d", i),
                       date,
                       base::StringPrintf("uid%05d", i), i % 5, i % 3));
  }

  SetupFolders(&test_folders, std::vector<AlbumInfo>(), AlbumImagesMap());
  VerifyFolderDirectoryList(test_folders);
}

TEST_F(PicasaFileUtilTest, AlbumExistence) {
  ScopedVector<TestFolder> test_folders;
  base::Time test_date = base::Time::FromLocalExploded(test_date_exploded);

  std::vector<AlbumInfo> albums;
  AlbumInfo info;
  info.name = "albumname";
  info.uid = "albumuid";
  info.timestamp = test_date;
  albums.push_back(info);

  AlbumImagesMap albums_images;
  albums_images[info.uid] = AlbumImages();

  SetupFolders(&test_folders, albums, albums_images);

  TestEmptyDirectory(std::string(kPicasaDirAlbums) + "/albumname 2013-04-16");
  TestNonexistentDirectory(std::string(kPicasaDirAlbums) +
                           "/albumname 2013-04-16/toodeep");
  TestNonexistentDirectory(std::string(kPicasaDirAlbums) + "/wrongname");
}

TEST_F(PicasaFileUtilTest, AlbumContents) {
  ScopedVector<TestFolder> test_folders;
  base::Time test_date = base::Time::FromLocalExploded(test_date_exploded);

  std::vector<AlbumInfo> albums;
  AlbumInfo info;
  info.name = "albumname";
  info.uid = "albumuid";
  info.timestamp = test_date;
  albums.push_back(info);

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());

  base::FilePath image_path = temp_dir.path().AppendASCII("img.jpg");
  ASSERT_TRUE(WriteJPEGHeader(image_path));

  AlbumImagesMap albums_images;
  albums_images[info.uid] = AlbumImages();
  albums_images[info.uid]["mapped_name.jpg"] = image_path;

  SetupFolders(&test_folders, albums, albums_images);

  FileSystemOperation::FileEntryList contents;
  FileSystemURL url =
      CreateURL(std::string(kPicasaDirAlbums) + "/albumname 2013-04-16");
  bool completed = false;
  ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);

  ASSERT_TRUE(completed);
  EXPECT_EQ(1u, contents.size());
  EXPECT_EQ("mapped_name.jpg",
            base::FilePath(contents.begin()->name).AsUTF8Unsafe());
  EXPECT_FALSE(contents.begin()->is_directory);

  // Create a snapshot file to verify the file path.
  base::RunLoop loop;
  base::File::Error error;
  base::FilePath platform_path_result;
  storage::FileSystemOperationRunner::SnapshotFileCallback snapshot_callback =
      base::Bind(&CreateSnapshotFileTestHelperCallback,
                 &loop,
                 &error,
                 &platform_path_result);
  operation_runner()->CreateSnapshotFile(
      CreateURL(std::string(kPicasaDirAlbums) +
                "/albumname 2013-04-16/mapped_name.jpg"),
      snapshot_callback);
  loop.Run();
  EXPECT_EQ(base::File::FILE_OK, error);
  EXPECT_EQ(image_path, platform_path_result);
}

}  // namespace picasa
