// 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 "chrome/browser/media_galleries/fileapi/itunes_file_util.h"

#include <set>
#include <string>
#include <vector>

#include "base/bind_helpers.h"
#include "base/file_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/media_galleries/fileapi/itunes_data_provider.h"
#include "chrome/browser/media_galleries/fileapi/media_path_filter.h"
#include "chrome/browser/media_galleries/imported_media_gallery_registry.h"
#include "content/public/browser/browser_thread.h"
#include "webkit/browser/fileapi/file_system_file_util.h"
#include "webkit/browser/fileapi/file_system_operation_context.h"
#include "webkit/browser/fileapi/file_system_url.h"
#include "webkit/browser/fileapi/native_file_util.h"
#include "webkit/common/blob/shareable_file_reference.h"
#include "webkit/common/fileapi/file_system_util.h"

using fileapi::DirectoryEntry;

namespace itunes {

namespace {

const char kiTunesLibraryXML[] = "iTunes Music Library.xml";
const char kiTunesMediaDir[] = "iTunes Media";

base::PlatformFileError MakeDirectoryFileInfo(
    base::PlatformFileInfo* file_info) {
  base::PlatformFileInfo result;
  result.is_directory = true;
  *file_info = result;
  return base::PLATFORM_FILE_OK;
}

}  // namespace

ItunesFileUtil::ItunesFileUtil(chrome::MediaPathFilter* media_path_filter)
    : chrome::NativeMediaFileUtil(media_path_filter),
      weak_factory_(this),
      imported_registry_(NULL) {
}

ItunesFileUtil::~ItunesFileUtil() {
}

void ItunesFileUtil::GetFileInfoOnTaskRunnerThread(
    scoped_ptr<fileapi::FileSystemOperationContext> context,
    const fileapi::FileSystemURL& url,
    const GetFileInfoCallback& callback) {
  GetDataProvider()->RefreshData(
      base::Bind(&ItunesFileUtil::GetFileInfoWithFreshDataProvider,
                 weak_factory_.GetWeakPtr(), base::Passed(&context), url,
                 callback));
}

void ItunesFileUtil::ReadDirectoryOnTaskRunnerThread(
    scoped_ptr<fileapi::FileSystemOperationContext> context,
    const fileapi::FileSystemURL& url,
    const ReadDirectoryCallback& callback) {
  GetDataProvider()->RefreshData(
      base::Bind(&ItunesFileUtil::ReadDirectoryWithFreshDataProvider,
                 weak_factory_.GetWeakPtr(), base::Passed(&context), url,
                 callback));
}

void ItunesFileUtil::CreateSnapshotFileOnTaskRunnerThread(
    scoped_ptr<fileapi::FileSystemOperationContext> context,
    const fileapi::FileSystemURL& url,
    const CreateSnapshotFileCallback& callback) {
  GetDataProvider()->RefreshData(
      base::Bind(&ItunesFileUtil::CreateSnapshotFileWithFreshDataProvider,
                 weak_factory_.GetWeakPtr(), base::Passed(&context), url,
                 callback));
}

// Contents of the iTunes media gallery:
//   /                                          - root directory
//   /iTunes Music Library.xml                  - library xml file
//   /iTunes Media/<Artist>/<Album>/<Track>     - tracks
//
base::PlatformFileError ItunesFileUtil::GetFileInfoSync(
    fileapi::FileSystemOperationContext* context,
    const fileapi::FileSystemURL& url,
    base::PlatformFileInfo* file_info,
    base::FilePath* platform_path) {
  std::vector<std::string> components;
  fileapi::VirtualPath::GetComponentsUTF8Unsafe(url.path(), &components);

  if (components.size() == 0)
    return MakeDirectoryFileInfo(file_info);

  if (components.size() == 1 && components[0] == kiTunesLibraryXML) {
    // We can't just call NativeMediaFileUtil::GetFileInfoSync() here because it
    // uses the MediaPathFilter. At this point, |library_path_| is known good
    // because GetFileInfoWithFreshDataProvider() gates access to this method.
    base::FilePath file_path = GetDataProvider()->library_path();
    if (platform_path)
      *platform_path = file_path;
    return fileapi::NativeFileUtil::GetFileInfo(file_path, file_info);
  }

  if (components[0] != kiTunesMediaDir || components.size() > 4)
    return base::PLATFORM_FILE_ERROR_NOT_FOUND;

  switch (components.size()) {
    case 1:
      return MakeDirectoryFileInfo(file_info);

    case 2:
      if (GetDataProvider()->KnownArtist(components[1]))
        return MakeDirectoryFileInfo(file_info);
      break;

    case 3:
      if (GetDataProvider()->KnownAlbum(components[1], components[2]))
        return MakeDirectoryFileInfo(file_info);
      break;

    case 4: {
      base::FilePath location =
          GetDataProvider()->GetTrackLocation(components[1], components[2],
                                              components[3]);
      if (!location.empty()) {
        return NativeMediaFileUtil::GetFileInfoSync(context, url, file_info,
                                                    platform_path);
      }
      break;
    }

    default:
      NOTREACHED();
  }

  return base::PLATFORM_FILE_ERROR_NOT_FOUND;
}

base::PlatformFileError ItunesFileUtil::ReadDirectorySync(
    fileapi::FileSystemOperationContext* context,
    const fileapi::FileSystemURL& url,
    EntryList* file_list) {
  DCHECK(file_list->empty());
  std::vector<std::string> components;
  fileapi::VirtualPath::GetComponentsUTF8Unsafe(url.path(), &components);

  if (components.size() == 0) {
    base::PlatformFileInfo xml_info;
    if (!file_util::GetFileInfo(GetDataProvider()->library_path(), &xml_info))
      return base::PLATFORM_FILE_ERROR_IO;
    file_list->push_back(DirectoryEntry(kiTunesLibraryXML,
                                        DirectoryEntry::FILE,
                                        xml_info.size, xml_info.last_modified));
    file_list->push_back(DirectoryEntry(kiTunesMediaDir,
                                        DirectoryEntry::DIRECTORY,
                                        0, base::Time()));
    return base::PLATFORM_FILE_OK;
  }

  if (components.size() == 1 && components[0] == kiTunesLibraryXML)
    return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;

  if (components[0] != kiTunesMediaDir || components.size() > 4)
    return base::PLATFORM_FILE_ERROR_NOT_FOUND;

  if (components.size() == 1) {
    std::set<ITunesDataProvider::ArtistName> artists =
        GetDataProvider()->GetArtistNames();
    std::set<ITunesDataProvider::ArtistName>::const_iterator it;
    for (it = artists.begin(); it != artists.end(); ++it)
      file_list->push_back(DirectoryEntry(*it, DirectoryEntry::DIRECTORY,
                                          0, base::Time()));
    return base::PLATFORM_FILE_OK;
  }

  if (components.size() == 2) {
    std::set<ITunesDataProvider::AlbumName> albums =
        GetDataProvider()->GetAlbumNames(components[1]);
    if (albums.size() == 0)
      return base::PLATFORM_FILE_ERROR_NOT_FOUND;
    std::set<ITunesDataProvider::AlbumName>::const_iterator it;
    for (it = albums.begin(); it != albums.end(); ++it)
      file_list->push_back(DirectoryEntry(*it, DirectoryEntry::DIRECTORY,
                                          0, base::Time()));
    return base::PLATFORM_FILE_OK;
  }

  if (components.size() == 3) {
    ITunesDataProvider::Album album =
        GetDataProvider()->GetAlbum(components[1], components[2]);
    if (album.size() == 0)
      return base::PLATFORM_FILE_ERROR_NOT_FOUND;
    ITunesDataProvider::Album::const_iterator it;
    for (it = album.begin(); it != album.end(); ++it) {
      base::PlatformFileInfo file_info;
      if (media_path_filter()->Match(it->second) &&
          file_util::GetFileInfo(it->second, &file_info)) {
        file_list->push_back(DirectoryEntry(it->first, DirectoryEntry::FILE,
                                            file_info.size,
                                            file_info.last_modified));
      }
    }
    return base::PLATFORM_FILE_OK;
  }

  // At this point, the only choice is one of two errors, but figuring out
  // which one is required.
  DCHECK_EQ(4UL, components.size());
  base::FilePath location;
  location = GetDataProvider()->GetTrackLocation(components[1], components[2],
                                                 components[3]);
  if (!location.empty())
    return base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY;
  return base::PLATFORM_FILE_ERROR_NOT_FOUND;
}

base::PlatformFileError ItunesFileUtil::CreateSnapshotFileSync(
    fileapi::FileSystemOperationContext* context,
    const fileapi::FileSystemURL& url,
    base::PlatformFileInfo* file_info,
    base::FilePath* platform_path,
    scoped_refptr<webkit_blob::ShareableFileReference>* file_ref) {
  DCHECK(!url.path().IsAbsolute());
  if (url.path() != base::FilePath().AppendASCII(kiTunesLibraryXML)) {
    return NativeMediaFileUtil::CreateSnapshotFileSync(context, url, file_info,
                                                       platform_path, file_ref);
  }

  // The following code is different than
  // NativeMediaFileUtil::CreateSnapshotFileSync in that it knows that the
  // library xml file is not a directory and it doesn't run mime sniffing on the
  // file. The only way to get here is by way of
  // CreateSnapshotFileWithFreshDataProvider() so the file has already been
  // parsed and deemed valid.
  *file_ref = scoped_refptr<webkit_blob::ShareableFileReference>();
  return GetFileInfoSync(context, url, file_info, platform_path);
}

base::PlatformFileError ItunesFileUtil::GetLocalFilePath(
    fileapi::FileSystemOperationContext* context,
    const fileapi::FileSystemURL& url,
    base::FilePath* local_file_path) {
  // Should only get here for files, i.e. the xml file and tracks.
  std::vector<std::string> components;
  fileapi::VirtualPath::GetComponentsUTF8Unsafe(url.path(), &components);

  if (components.size() == 1 && components[0] == kiTunesLibraryXML) {
    *local_file_path = GetDataProvider()->library_path();
    return base::PLATFORM_FILE_OK;
  }

  if (components[0] != kiTunesMediaDir || components.size() != 4)
    return base::PLATFORM_FILE_ERROR_NOT_FOUND;

  *local_file_path = GetDataProvider()->GetTrackLocation(components[1],
                                                         components[2],
                                                         components[3]);
  if (!local_file_path->empty())
    return base::PLATFORM_FILE_OK;

  return base::PLATFORM_FILE_ERROR_NOT_FOUND;
}

void ItunesFileUtil::GetFileInfoWithFreshDataProvider(
    scoped_ptr<fileapi::FileSystemOperationContext> context,
    const fileapi::FileSystemURL& url,
    const GetFileInfoCallback& callback,
    bool valid_parse) {
  if (!valid_parse) {
    if (!callback.is_null()) {
      content::BrowserThread::PostTask(
          content::BrowserThread::IO,
          FROM_HERE,
          base::Bind(callback, base::PLATFORM_FILE_ERROR_IO,
                     base::PlatformFileInfo()));
    }
    return;
  }
  NativeMediaFileUtil::GetFileInfoOnTaskRunnerThread(context.Pass(), url,
                                                     callback);
}

void ItunesFileUtil::ReadDirectoryWithFreshDataProvider(
    scoped_ptr<fileapi::FileSystemOperationContext> context,
    const fileapi::FileSystemURL& url,
    const ReadDirectoryCallback& callback,
    bool valid_parse) {
  if (!valid_parse) {
    if (!callback.is_null()) {
      content::BrowserThread::PostTask(
          content::BrowserThread::IO,
          FROM_HERE,
          base::Bind(callback, base::PLATFORM_FILE_ERROR_IO, EntryList(),
                     false));
    }
    return;
  }
  NativeMediaFileUtil::ReadDirectoryOnTaskRunnerThread(context.Pass(), url,
                                                       callback);
}

void ItunesFileUtil::CreateSnapshotFileWithFreshDataProvider(
    scoped_ptr<fileapi::FileSystemOperationContext> context,
    const fileapi::FileSystemURL& url,
    const CreateSnapshotFileCallback& callback,
    bool valid_parse) {
  if (!valid_parse) {
    if (!callback.is_null()) {
      base::PlatformFileInfo file_info;
      base::FilePath platform_path;
      scoped_refptr<webkit_blob::ShareableFileReference> file_ref;
      content::BrowserThread::PostTask(
          content::BrowserThread::IO,
          FROM_HERE,
          base::Bind(callback, base::PLATFORM_FILE_ERROR_IO, file_info,
                     platform_path, file_ref));
    }
    return;
  }
  NativeMediaFileUtil::CreateSnapshotFileOnTaskRunnerThread(context.Pass(), url,
                                                            callback);
}

ITunesDataProvider* ItunesFileUtil::GetDataProvider() {
  if (!imported_registry_)
    imported_registry_ = chrome::ImportedMediaGalleryRegistry::GetInstance();
  return imported_registry_->ITunesDataProvider();
}

}  // namespace itunes
