// 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.h"
#include "base/bind_helpers.h"
#include "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/synchronization/waitable_event.h"
#include "base/time/time.h"
#include "chrome/browser/media_galleries/fileapi/itunes_data_provider.h"
#include "chrome/browser/media_galleries/fileapi/itunes_file_util.h"
#include "chrome/browser/media_galleries/fileapi/media_file_system_backend.h"
#include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_file_system_options.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/browser/fileapi/async_file_util.h"
#include "webkit/browser/fileapi/external_mount_points.h"
#include "webkit/browser/fileapi/file_system_context.h"
#include "webkit/browser/fileapi/file_system_operation_context.h"
#include "webkit/browser/fileapi/file_system_operation_runner.h"
#include "webkit/browser/quota/mock_special_storage_policy.h"

using fileapi::FileSystemFileUtil;
using fileapi::FileSystemOperationContext;
using fileapi::FileSystemOperation;
using fileapi::FileSystemURL;

namespace itunes {

namespace {

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

void ReadDirectoryTestHelper(fileapi::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();
}

}  // namespace

class TestITunesDataProvider : public ITunesDataProvider {
 public:
  explicit TestITunesDataProvider(const base::FilePath& fake_library_path)
     : ITunesDataProvider(fake_library_path) {
    EXPECT_TRUE(fake_auto_add_dir_.CreateUniqueTempDir());
  }

  virtual ~TestITunesDataProvider() {}

  virtual void RefreshData(const ReadyCallback& ready_callback) OVERRIDE {
    ready_callback.Run(true /* success */);
  }

  virtual const base::FilePath& auto_add_path() const OVERRIDE {
    return fake_auto_add_dir_.path();
  }

  void SetProvideAutoAddDir(bool provide_auto_add_dir) {
    if (provide_auto_add_dir) {
      if (!fake_auto_add_dir_.IsValid())
        ASSERT_TRUE(fake_auto_add_dir_.CreateUniqueTempDir());
    } else {
      ASSERT_TRUE(fake_auto_add_dir_.Delete());
    }
  }

 private:
  base::ScopedTempDir fake_auto_add_dir_;
};

class TestITunesFileUtil : public ITunesFileUtil {
 public:
  explicit TestITunesFileUtil(MediaPathFilter* media_path_filter,
                              ITunesDataProvider* data_provider)
      : ITunesFileUtil(media_path_filter),
        data_provider_(data_provider) {
  }
  virtual ~TestITunesFileUtil() {}

 private:
  virtual ITunesDataProvider* GetDataProvider() OVERRIDE {
    return data_provider_;
  }

  ITunesDataProvider* data_provider_;
};

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

  virtual fileapi::AsyncFileUtil*
  GetAsyncFileUtil(fileapi::FileSystemType type) OVERRIDE {
    if (type != fileapi::kFileSystemTypeItunes)
      return NULL;

    return test_file_util_.get();
  }

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

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

  void SetUpDataProvider() {
    ASSERT_TRUE(fake_library_dir_.CreateUniqueTempDir());
    ASSERT_EQ(
        0,
        file_util::WriteFile(
            fake_library_dir_.path().AppendASCII(kITunesLibraryXML),
            NULL,
            0));

    itunes_data_provider_.reset(
        new TestITunesDataProvider(fake_library_dir_.path()));
  }

  virtual void SetUp() OVERRIDE {
    ASSERT_TRUE(profile_dir_.CreateUniqueTempDir());

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

    // Initialize fake ItunesDataProvider on media task runner thread.
    MediaFileSystemBackend::MediaTaskRunner()->PostTask(
        FROM_HERE,
        base::Bind(&ItunesFileUtilTest::SetUpDataProvider,
                   base::Unretained(this)));
    base::WaitableEvent event(true, false /* initially_signalled */);
    MediaFileSystemBackend::MediaTaskRunner()->PostTask(
        FROM_HERE,
        base::Bind(&base::WaitableEvent::Signal, base::Unretained(&event)));
    event.Wait();

    media_path_filter_.reset(new MediaPathFilter());
    ScopedVector<fileapi::FileSystemBackend> additional_providers;
    additional_providers.push_back(new TestMediaFileSystemBackend(
        profile_dir_.path(),
        new TestITunesFileUtil(media_path_filter_.get(),
                               itunes_data_provider_.get())));

    file_system_context_ = new fileapi::FileSystemContext(
        base::MessageLoopProxy::current().get(),
        base::MessageLoopProxy::current().get(),
        fileapi::ExternalMountPoints::CreateRefCounted().get(),
        storage_policy.get(),
        NULL,
        additional_providers.Pass(),
        profile_dir_.path(),
        fileapi::CreateAllowFileAccessOptions());
  }

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

    ASSERT_FALSE(completed);
  }

  FileSystemURL CreateURL(const std::string& virtual_path) const {
    return file_system_context_->CreateCrackedFileSystemURL(
        GURL("http://www.example.com"), fileapi::kFileSystemTypeItunes,
        base::FilePath::FromUTF8Unsafe(virtual_path));
  }

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

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

  TestITunesDataProvider* data_provider() const {
    return itunes_data_provider_.get();
  }

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

  base::ScopedTempDir profile_dir_;
  base::ScopedTempDir fake_library_dir_;

  scoped_refptr<fileapi::FileSystemContext> file_system_context_;
  scoped_ptr<MediaPathFilter> media_path_filter_;
  scoped_ptr<TestITunesDataProvider> itunes_data_provider_;

  DISALLOW_COPY_AND_ASSIGN(ItunesFileUtilTest);
};

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

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

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

  EXPECT_EQ(base::FilePath::FromUTF8Unsafe(kITunesLibraryXML).value(),
            contents.front().name);
  EXPECT_EQ(base::FilePath::FromUTF8Unsafe(kITunesMediaDir).value(),
            contents.back().name);
}

TEST_F(ItunesFileUtilTest, ItunesMediaDirectoryContentsNoAutoAdd) {
  data_provider()->SetProvideAutoAddDir(false);

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

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

  EXPECT_TRUE(contents.front().is_directory);
  EXPECT_EQ(base::FilePath::FromUTF8Unsafe(kITunesMusicDir).value(),
            contents.back().name);
}

TEST_F(ItunesFileUtilTest, ItunesMediaDirectoryContentsAutoAdd) {
  data_provider()->SetProvideAutoAddDir(true);

  FileSystemOperation::FileEntryList contents;
  FileSystemURL url = CreateURL(kITunesMediaDir);
  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(base::FilePath::FromUTF8Unsafe(kITunesAutoAddDir).value(),
            contents.front().name);
  EXPECT_EQ(base::FilePath::FromUTF8Unsafe(kITunesMusicDir).value(),
            contents.back().name);
}

TEST_F(ItunesFileUtilTest, ItunesAutoAddDirEnumerate) {
  data_provider()->SetProvideAutoAddDir(true);
  ASSERT_EQ(0, file_util::WriteFile(
      data_provider()->auto_add_path().AppendASCII("baz.ogg"), NULL, 0));

  FileSystemOperation::FileEntryList contents;
  FileSystemURL url = CreateURL(
      std::string(kITunesMediaDir) + "/" + kITunesAutoAddDir);
  bool completed = false;

  ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);
  ASSERT_TRUE(completed);
  ASSERT_EQ(1u, contents.size());
  EXPECT_FALSE(contents.front().is_directory);
  EXPECT_EQ(base::FilePath().AppendASCII("baz.ogg").value(),
            contents.front().name);
}

TEST_F(ItunesFileUtilTest, ItunesAutoAddDirEnumerateNested) {
  data_provider()->SetProvideAutoAddDir(true);
  base::FilePath nested_dir =
      data_provider()->auto_add_path().AppendASCII("foo").AppendASCII("bar");
  ASSERT_TRUE(file_util::CreateDirectory(nested_dir));
  ASSERT_EQ(0,
            file_util::WriteFile(nested_dir.AppendASCII("baz.ogg"), NULL, 0));

  FileSystemOperation::FileEntryList contents;
  FileSystemURL url = CreateURL(
      std::string(kITunesMediaDir) + "/" + kITunesAutoAddDir);
  bool completed = false;

  ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);
  ASSERT_TRUE(completed);
  ASSERT_EQ(1u, contents.size());
  EXPECT_TRUE(contents.front().is_directory);
  EXPECT_EQ(base::FilePath().AppendASCII("foo").value(), contents.front().name);

  contents.clear();
  url = CreateURL(
      std::string(kITunesMediaDir) + "/" + kITunesAutoAddDir + "/foo");
  completed = false;
  ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);
  ASSERT_TRUE(completed);
  ASSERT_EQ(1u, contents.size());
  EXPECT_TRUE(contents.front().is_directory);
  EXPECT_EQ(base::FilePath().AppendASCII("bar").value(), contents.front().name);

  contents.clear();
  url = CreateURL(
      std::string(kITunesMediaDir) + "/" + kITunesAutoAddDir + "/foo/bar");
  completed = false;
  ReadDirectoryTestHelper(operation_runner(), url, &contents, &completed);
  ASSERT_TRUE(completed);
  ASSERT_EQ(1u, contents.size());
  EXPECT_FALSE(contents.front().is_directory);
  EXPECT_EQ(base::FilePath().AppendASCII("baz.ogg").value(),
            contents.front().name);
}

}  // namespace itunes
