/*
 * 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/DOMFileSystem.h"

#include "core/fileapi/BlobCallback.h"
#include "modules/filesystem/DOMFilePath.h"
#include "modules/filesystem/DirectoryEntry.h"
#include "modules/filesystem/FileEntry.h"
#include "modules/filesystem/FileSystemCallbacks.h"
#include "modules/filesystem/FileWriter.h"
#include "modules/filesystem/FileWriterBaseCallback.h"
#include "modules/filesystem/FileWriterCallback.h"
#include "modules/filesystem/MetadataCallback.h"
#include "platform/FileMetadata.h"
#include "platform/weborigin/SecurityOrigin.h"
#include "public/platform/Platform.h"
#include "public/platform/WebFileSystem.h"
#include "public/platform/WebFileSystemCallbacks.h"
#include "public/platform/WebSecurityOrigin.h"
#include "wtf/text/StringBuilder.h"
#include "wtf/text/WTFString.h"
#include <memory>

namespace blink {

// static
DOMFileSystem* DOMFileSystem::create(ExecutionContext* context,
                                     const String& name,
                                     FileSystemType type,
                                     const KURL& rootURL) {
  DOMFileSystem* fileSystem(new DOMFileSystem(context, name, type, rootURL));
  fileSystem->suspendIfNeeded();
  return fileSystem;
}

DOMFileSystem* DOMFileSystem::createIsolatedFileSystem(
    ExecutionContext* context,
    const String& filesystemId) {
  if (filesystemId.isEmpty())
    return 0;

  StringBuilder filesystemName;
  filesystemName.append(Platform::current()->fileSystemCreateOriginIdentifier(
      WebSecurityOrigin(context->getSecurityOrigin())));
  filesystemName.append(":Isolated_");
  filesystemName.append(filesystemId);

  // The rootURL created here is going to be attached to each filesystem request
  // and is to be validated each time the request is being handled.
  StringBuilder rootURL;
  rootURL.append("filesystem:");
  rootURL.append(context->getSecurityOrigin()->toString());
  rootURL.append('/');
  rootURL.append(isolatedPathPrefix);
  rootURL.append('/');
  rootURL.append(filesystemId);
  rootURL.append('/');

  return DOMFileSystem::create(context, filesystemName.toString(),
                               FileSystemTypeIsolated,
                               KURL(ParsedURLString, rootURL.toString()));
}

DOMFileSystem::DOMFileSystem(ExecutionContext* context,
                             const String& name,
                             FileSystemType type,
                             const KURL& rootURL)
    : DOMFileSystemBase(context, name, type, rootURL),
      ActiveScriptWrappable(this),
      ActiveDOMObject(context),
      m_numberOfPendingCallbacks(0),
      m_rootEntry(DirectoryEntry::create(this, DOMFilePath::root)) {}

DirectoryEntry* DOMFileSystem::root() const {
  return m_rootEntry.get();
}

void DOMFileSystem::addPendingCallbacks() {
  ++m_numberOfPendingCallbacks;
}

void DOMFileSystem::removePendingCallbacks() {
  ASSERT(m_numberOfPendingCallbacks > 0);
  --m_numberOfPendingCallbacks;
}

bool DOMFileSystem::hasPendingActivity() const {
  ASSERT(m_numberOfPendingCallbacks >= 0);
  return m_numberOfPendingCallbacks;
}

void DOMFileSystem::reportError(ErrorCallbackBase* errorCallback,
                                FileError::ErrorCode fileError) {
  reportError(getExecutionContext(), errorCallback, fileError);
}

void DOMFileSystem::reportError(ExecutionContext* executionContext,
                                ErrorCallbackBase* errorCallback,
                                FileError::ErrorCode fileError) {
  if (errorCallback)
    scheduleCallback(
        executionContext,
        createSameThreadTask(&ErrorCallbackBase::invoke,
                             wrapPersistent(errorCallback), fileError));
}

namespace {

class ConvertToFileWriterCallback : public FileWriterBaseCallback {
 public:
  static ConvertToFileWriterCallback* create(FileWriterCallback* callback) {
    return new ConvertToFileWriterCallback(callback);
  }

  DEFINE_INLINE_TRACE() {
    visitor->trace(m_callback);
    FileWriterBaseCallback::trace(visitor);
  }

  void handleEvent(FileWriterBase* fileWriterBase) {
    m_callback->handleEvent(static_cast<FileWriter*>(fileWriterBase));
  }

 private:
  explicit ConvertToFileWriterCallback(FileWriterCallback* callback)
      : m_callback(callback) {}
  Member<FileWriterCallback> m_callback;
};

}  // namespace

void DOMFileSystem::createWriter(const FileEntry* fileEntry,
                                 FileWriterCallback* successCallback,
                                 ErrorCallbackBase* errorCallback) {
  ASSERT(fileEntry);

  if (!fileSystem()) {
    reportError(errorCallback, FileError::kAbortErr);
    return;
  }

  FileWriter* fileWriter = FileWriter::create(getExecutionContext());
  FileWriterBaseCallback* conversionCallback =
      ConvertToFileWriterCallback::create(successCallback);
  std::unique_ptr<AsyncFileSystemCallbacks> callbacks =
      FileWriterBaseCallbacks::create(fileWriter, conversionCallback,
                                      errorCallback, m_context);
  fileSystem()->createFileWriter(createFileSystemURL(fileEntry), fileWriter,
                                 std::move(callbacks));
}

void DOMFileSystem::createFile(const FileEntry* fileEntry,
                               BlobCallback* successCallback,
                               ErrorCallbackBase* errorCallback) {
  KURL fileSystemURL = createFileSystemURL(fileEntry);
  if (!fileSystem()) {
    reportError(errorCallback, FileError::kAbortErr);
    return;
  }

  fileSystem()->createSnapshotFileAndReadMetadata(
      fileSystemURL,
      SnapshotFileCallback::create(this, fileEntry->name(), fileSystemURL,
                                   successCallback, errorCallback, m_context));
}

DEFINE_TRACE(DOMFileSystem) {
  DOMFileSystemBase::trace(visitor);
  ActiveDOMObject::trace(visitor);
  visitor->trace(m_rootEntry);
}

}  // namespace blink
