/*
 * Copyright (C) 2010 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "modules/filesystem/FileSystemCallbacks.h"

#include "core/dom/ExecutionContext.h"
#include "core/fileapi/BlobCallback.h"
#include "core/fileapi/File.h"
#include "core/fileapi/FileError.h"
#include "core/html/VoidCallback.h"
#include "modules/filesystem/DOMFilePath.h"
#include "modules/filesystem/DOMFileSystem.h"
#include "modules/filesystem/DOMFileSystemBase.h"
#include "modules/filesystem/DirectoryEntry.h"
#include "modules/filesystem/DirectoryReader.h"
#include "modules/filesystem/Entry.h"
#include "modules/filesystem/EntryCallback.h"
#include "modules/filesystem/ErrorCallback.h"
#include "modules/filesystem/FileEntry.h"
#include "modules/filesystem/FileSystemCallback.h"
#include "modules/filesystem/FileWriterBase.h"
#include "modules/filesystem/FileWriterBaseCallback.h"
#include "modules/filesystem/Metadata.h"
#include "modules/filesystem/MetadataCallback.h"
#include "platform/FileMetadata.h"
#include "public/platform/WebFileWriter.h"
#include "wtf/PtrUtil.h"
#include <memory>

namespace blink {

FileSystemCallbacksBase::FileSystemCallbacksBase(ErrorCallbackBase* errorCallback, DOMFileSystemBase* fileSystem, ExecutionContext* context)
    : m_errorCallback(errorCallback)
    , m_fileSystem(fileSystem)
    , m_executionContext(context)
{
    if (m_fileSystem)
        m_fileSystem->addPendingCallbacks();
}

FileSystemCallbacksBase::~FileSystemCallbacksBase()
{
    if (m_fileSystem)
        m_fileSystem->removePendingCallbacks();
}

void FileSystemCallbacksBase::didFail(int code)
{
    if (m_errorCallback)
        invokeOrScheduleCallback(m_errorCallback.release(), static_cast<FileError::ErrorCode>(code));
}

bool FileSystemCallbacksBase::shouldScheduleCallback() const
{
    return !shouldBlockUntilCompletion() && m_executionContext && m_executionContext->activeDOMObjectsAreSuspended();
}

template <typename CB, typename CBArg>
void FileSystemCallbacksBase::invokeOrScheduleCallback(CB* callback, CBArg arg)
{
    DCHECK(callback);
    if (callback) {
        if (shouldScheduleCallback())
            DOMFileSystem::scheduleCallback(m_executionContext.get(), createSameThreadTask(&CB::invoke, wrapPersistent(callback), arg));
        else
            callback->invoke(arg);
    }
    m_executionContext.clear();
}

template <typename CB, typename CBArg>
void FileSystemCallbacksBase::handleEventOrScheduleCallback(CB* callback, CBArg* arg)
{
    DCHECK(callback);
    if (callback) {
        if (shouldScheduleCallback())
            DOMFileSystem::scheduleCallback(m_executionContext.get(), createSameThreadTask(&CB::handleEvent, wrapPersistent(callback), wrapPersistent(arg)));
        else
            callback->handleEvent(arg);
    }
    m_executionContext.clear();
}

template <typename CB>
void FileSystemCallbacksBase::handleEventOrScheduleCallback(CB* callback)
{
    DCHECK(callback);
    if (callback) {
        if (shouldScheduleCallback())
            DOMFileSystem::scheduleCallback(m_executionContext.get(), createSameThreadTask(&CB::handleEvent, wrapPersistent(callback)));
        else
            callback->handleEvent();
    }
    m_executionContext.clear();
}

// ScriptErrorCallback --------------------------------------------------------

// static
ScriptErrorCallback* ScriptErrorCallback::wrap(ErrorCallback* callback)
{
    // DOMFileSystem operations take an optional (nullable) callback. If a
    // script callback was not passed, don't bother creating a dummy wrapper
    // and checking during invoke().
    if (!callback)
        return nullptr;
    return new ScriptErrorCallback(callback);
}

DEFINE_TRACE(ScriptErrorCallback)
{
    ErrorCallbackBase::trace(visitor);
    visitor->trace(m_callback);
}

void ScriptErrorCallback::invoke(FileError::ErrorCode error)
{
    m_callback->handleEvent(FileError::createDOMException(error));
};

ScriptErrorCallback::ScriptErrorCallback(ErrorCallback* callback)
    : m_callback(callback)
{
}

// EntryCallbacks -------------------------------------------------------------

std::unique_ptr<AsyncFileSystemCallbacks> EntryCallbacks::create(EntryCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context, DOMFileSystemBase* fileSystem, const String& expectedPath, bool isDirectory)
{
    return wrapUnique(new EntryCallbacks(successCallback, errorCallback, context, fileSystem, expectedPath, isDirectory));
}

EntryCallbacks::EntryCallbacks(EntryCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context, DOMFileSystemBase* fileSystem, const String& expectedPath, bool isDirectory)
    : FileSystemCallbacksBase(errorCallback, fileSystem, context)
    , m_successCallback(successCallback)
    , m_expectedPath(expectedPath)
    , m_isDirectory(isDirectory)
{
}

void EntryCallbacks::didSucceed()
{
    if (m_successCallback) {
        if (m_isDirectory)
            handleEventOrScheduleCallback(m_successCallback.release(), DirectoryEntry::create(m_fileSystem, m_expectedPath));
        else
            handleEventOrScheduleCallback(m_successCallback.release(), FileEntry::create(m_fileSystem, m_expectedPath));
    }
}

// EntriesCallbacks -----------------------------------------------------------

std::unique_ptr<AsyncFileSystemCallbacks> EntriesCallbacks::create(EntriesCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context, DirectoryReaderBase* directoryReader, const String& basePath)
{
    return wrapUnique(new EntriesCallbacks(successCallback, errorCallback, context, directoryReader, basePath));
}

EntriesCallbacks::EntriesCallbacks(EntriesCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context, DirectoryReaderBase* directoryReader, const String& basePath)
    : FileSystemCallbacksBase(errorCallback, directoryReader->filesystem(), context)
    , m_successCallback(successCallback)
    , m_directoryReader(directoryReader)
    , m_basePath(basePath)
{
    ASSERT(m_directoryReader);
}

void EntriesCallbacks::didReadDirectoryEntry(const String& name, bool isDirectory)
{
    if (isDirectory)
        m_entries.append(DirectoryEntry::create(m_directoryReader->filesystem(), DOMFilePath::append(m_basePath, name)));
    else
        m_entries.append(FileEntry::create(m_directoryReader->filesystem(), DOMFilePath::append(m_basePath, name)));
}

void EntriesCallbacks::didReadDirectoryEntries(bool hasMore)
{
    m_directoryReader->setHasMoreEntries(hasMore);
    EntryHeapVector entries;
    entries.swap(m_entries);
    // FIXME: delay the callback iff shouldScheduleCallback() is true.
    if (m_successCallback)
        m_successCallback->handleEvent(entries);
}

// FileSystemCallbacks --------------------------------------------------------

std::unique_ptr<AsyncFileSystemCallbacks> FileSystemCallbacks::create(FileSystemCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context, FileSystemType type)
{
    return wrapUnique(new FileSystemCallbacks(successCallback, errorCallback, context, type));
}

FileSystemCallbacks::FileSystemCallbacks(FileSystemCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context, FileSystemType type)
    : FileSystemCallbacksBase(errorCallback, nullptr, context)
    , m_successCallback(successCallback)
    , m_type(type)
{
}

void FileSystemCallbacks::didOpenFileSystem(const String& name, const KURL& rootURL)
{
    if (m_successCallback)
        handleEventOrScheduleCallback(m_successCallback.release(), DOMFileSystem::create(m_executionContext.get(), name, m_type, rootURL));
}

// ResolveURICallbacks --------------------------------------------------------

std::unique_ptr<AsyncFileSystemCallbacks> ResolveURICallbacks::create(EntryCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context)
{
    return wrapUnique(new ResolveURICallbacks(successCallback, errorCallback, context));
}

ResolveURICallbacks::ResolveURICallbacks(EntryCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context)
    : FileSystemCallbacksBase(errorCallback, nullptr, context)
    , m_successCallback(successCallback)
{
}

void ResolveURICallbacks::didResolveURL(const String& name, const KURL& rootURL, FileSystemType type, const String& filePath, bool isDirectory)
{
    DOMFileSystem* filesystem = DOMFileSystem::create(m_executionContext.get(), name, type, rootURL);
    DirectoryEntry* root = filesystem->root();

    String absolutePath;
    if (!DOMFileSystemBase::pathToAbsolutePath(type, root, filePath, absolutePath)) {
        invokeOrScheduleCallback(m_errorCallback.release(), FileError::INVALID_MODIFICATION_ERR);
        return;
    }

    if (isDirectory)
        handleEventOrScheduleCallback(m_successCallback.release(), DirectoryEntry::create(filesystem, absolutePath));
    else
        handleEventOrScheduleCallback(m_successCallback.release(), FileEntry::create(filesystem, absolutePath));
}

// MetadataCallbacks ----------------------------------------------------------

std::unique_ptr<AsyncFileSystemCallbacks> MetadataCallbacks::create(MetadataCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context, DOMFileSystemBase* fileSystem)
{
    return wrapUnique(new MetadataCallbacks(successCallback, errorCallback, context, fileSystem));
}

MetadataCallbacks::MetadataCallbacks(MetadataCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context, DOMFileSystemBase* fileSystem)
    : FileSystemCallbacksBase(errorCallback, fileSystem, context)
    , m_successCallback(successCallback)
{
}

void MetadataCallbacks::didReadMetadata(const FileMetadata& metadata)
{
    if (m_successCallback)
        handleEventOrScheduleCallback(m_successCallback.release(), Metadata::create(metadata));
}

// FileWriterBaseCallbacks ----------------------------------------------------

std::unique_ptr<AsyncFileSystemCallbacks> FileWriterBaseCallbacks::create(FileWriterBase* fileWriter, FileWriterBaseCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context)
{
    return wrapUnique(new FileWriterBaseCallbacks(fileWriter, successCallback, errorCallback, context));
}

FileWriterBaseCallbacks::FileWriterBaseCallbacks(FileWriterBase* fileWriter, FileWriterBaseCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context)
    : FileSystemCallbacksBase(errorCallback, nullptr, context)
    , m_fileWriter(fileWriter)
    , m_successCallback(successCallback)
{
}

void FileWriterBaseCallbacks::didCreateFileWriter(std::unique_ptr<WebFileWriter> fileWriter, long long length)
{
    m_fileWriter->initialize(std::move(fileWriter), length);
    if (m_successCallback)
        handleEventOrScheduleCallback(m_successCallback.release(), m_fileWriter.release());
}

// SnapshotFileCallback -------------------------------------------------------

std::unique_ptr<AsyncFileSystemCallbacks> SnapshotFileCallback::create(DOMFileSystemBase* filesystem, const String& name, const KURL& url, BlobCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context)
{
    return wrapUnique(new SnapshotFileCallback(filesystem, name, url, successCallback, errorCallback, context));
}

SnapshotFileCallback::SnapshotFileCallback(DOMFileSystemBase* filesystem, const String& name, const KURL& url, BlobCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context)
    : FileSystemCallbacksBase(errorCallback, filesystem, context)
    , m_name(name)
    , m_url(url)
    , m_successCallback(successCallback)
{
}

void SnapshotFileCallback::didCreateSnapshotFile(const FileMetadata& metadata, PassRefPtr<BlobDataHandle> snapshot)
{
    if (!m_successCallback)
        return;

    // We can't directly use the snapshot blob data handle because the content type on it hasn't been set.
    // The |snapshot| param is here to provide a a chain of custody thru thread bridging that is held onto until
    // *after* we've coined a File with a new handle that has the correct type set on it. This allows the
    // blob storage system to track when a temp file can and can't be safely deleted.

    handleEventOrScheduleCallback(m_successCallback.release(), DOMFileSystemBase::createFile(metadata, m_url, m_fileSystem->type(), m_name));
}

// VoidCallbacks --------------------------------------------------------------

std::unique_ptr<AsyncFileSystemCallbacks> VoidCallbacks::create(VoidCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context, DOMFileSystemBase* fileSystem)
{
    return wrapUnique(new VoidCallbacks(successCallback, errorCallback, context, fileSystem));
}

VoidCallbacks::VoidCallbacks(VoidCallback* successCallback, ErrorCallbackBase* errorCallback, ExecutionContext* context, DOMFileSystemBase* fileSystem)
    : FileSystemCallbacksBase(errorCallback, fileSystem, context)
    , m_successCallback(successCallback)
{
}

void VoidCallbacks::didSucceed()
{
    if (m_successCallback)
        handleEventOrScheduleCallback(m_successCallback.release());
}

} // namespace blink
