// Copyright 2014 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.

'use strict';

// Metadata is stored in files as serialized to JSON maps. See contents of
// example1.fake and example2.fake.

// Multiple volumes can be opened at the same time. The key is the
// fileSystemId, which is the same as the file's displayPath.
// The value is a Volume object.
var volumes = {};

// Defines a volume object that contains information about a mounted file
// system.
function Volume(entry, metadata, opt_openedFiles) {
  // Used for restoring the opened file entry after resuming the event page.
  this.entry = entry;

  // The volume metadata.
  this.metadata = [];
  for (var path in metadata) {
    this.metadata[path] = metadata[path];
    // Date object is serialized in JSON as string.
    this.metadata[path].modificationTime =
        new Date(metadata[path].modificationTime);
  }

  // A map with currently opened files. The key is a requestId value from the
  // openFileRequested event, and the value is the file path.
  this.openedFiles = opt_openedFiles ? opt_openedFiles : {};
};

function onUnmountRequested(options, onSuccess, onError) {
  if (Object.keys(volumes[options.fileSystemId].openedFiles).length != 0) {
    onError('IN_USE');
    return;
  }

  chrome.fileSystemProvider.unmount(
      {fileSystemId: options.fileSystemId},
      function() {
        delete volumes[options.fileSystemId];
        saveState(); // Remove volume from local storage state.
        onSuccess();
      },
      function() {
        onError('FAILED');
      });
};

function onGetMetadataRequested(options, onSuccess, onError) {
  restoreState(options.fileSystemId, function () {
    var entryMetadata =
        volumes[options.fileSystemId].metadata[options.entryPath];
    if (!entryMetadata)
      error('NOT_FOUND');
    else
      onSuccess(entryMetadata);
  }, onError);
};

function onReadDirectoryRequested(options, onSuccess, onError) {
  restoreState(options.fileSystemId, function () {
    var directoryMetadata =
        volumes[options.fileSystemId].metadata[options.directoryPath];
    if (!directoryMetadata) {
      onError('NOT_FOUND');
      return;
    }
    if (!directoryMetadata.isDirectory) {
      onError('NOT_A_DIRECTORY');
      return;
    }

    // Retrieve directory contents from metadata.
    var entries = [];
    for (var entry in volumes[options.fileSystemId].metadata) {
      // Do not add itself on the list.
      if (entry == options.directoryPath)
        continue;
      // Check if the entry is a child of the requested directory.
      if (entry.indexOf(options.directoryPath) != 0)
        continue;
      // Restrict to direct children only.
      if (entry.substring(options.directoryPath.length + 1).indexOf('/') != -1)
        continue;

      entries.push(volumes[options.fileSystemId].metadata[entry]);
    }
    onSuccess(entries, false /* Last call. */);
  }, onError);
};

function onOpenFileRequested(options, onSuccess, onError) {
  restoreState(options.fileSystemId, function () {
    if (options.mode != 'READ' || options.create) {
      onError('INVALID_OPERATION');
    } else {
      volumes[options.fileSystemId].openedFiles[options.requestId] =
          options.filePath;
      onSuccess();
    }
  }, onError);
};

function onCloseFileRequested(options, onSuccess, onError) {
  restoreState(options.fileSystemId, function () {
    if (!volumes[options.fileSystemId].openedFiles[options.openRequestId]) {
      onError('INVALID_OPERATION');
    } else {
      delete volumes[options.fileSystemId].openedFiles[options.openRequestId];
      onSuccess();
    }
  }, onError);
};

function onReadFileRequested(options, onSuccess, onError) {
  restoreState(options.fileSystemId, function () {
    var filePath =
        volumes[options.fileSystemId].openedFiles[options.openRequestId];
    if (!filePath) {
      onError('INVALID_OPERATION');
      return;
    }

    var contents = volumes[options.fileSystemId].metadata[filePath].contents;

    // Write the contents as ASCII text.
    var buffer = new ArrayBuffer(options.length);
    var bufferView = new Uint8Array(buffer);
    for (var i = 0; i < options.length; i++) {
      bufferView[i] = contents.charCodeAt(i);
    }

    onSuccess(buffer, false /* Last call. */);
  }, onError);
};

// Saves state in case of restarts, event page suspend, crashes, etc.
function saveState() {
  var state = {};
  for (var volumeId in volumes) {
    var entryId = chrome.fileSystem.retainEntry(volumes[volumeId].entry);
    state[volumeId] = {
      entryId: entryId,
      openedFiles: volumes[volumeId].openedFiles
    };
  }
  chrome.storage.local.set({state: state});
}

// Restores metadata for the passed file system ID.
function restoreState(fileSystemId, onSuccess, onError) {
  chrome.storage.local.get(['state'], function(result) {
    // Check if metadata for the given file system is alread in memory.
    if (volumes[fileSystemId]) {
      onSuccess();
      return;
    }

    chrome.fileSystem.restoreEntry(
        result.state[fileSystemId].entryId,
        function(entry) {
          readMetadataFromFile(entry,
              function(metadata) {
                volumes[fileSystemId] = new Volume(entry, metadata,
                    result.state[fileSystemId].openedFiles);
                onSuccess();
              }, onError);
        });
  });
}

// Reads metadata from a file and returns it with the onSuccess callback.
function readMetadataFromFile(entry, onSuccess, onError) {
  entry.file(function(file) {
    var fileReader = new FileReader();
    fileReader.onload = function(event) {
      onSuccess(JSON.parse(event.target.result));
    };

    fileReader.onerror = function(event) {
      onError('FAILED');
    };

    fileReader.readAsText(file);
  });
}

// Event called on opening a file with the extension or mime type
// declared in the manifest file.
chrome.app.runtime.onLaunched.addListener(function(event) {
  event.items.forEach(function(item) {
    readMetadataFromFile(item.entry,
        function(metadata) {
          // Mount the volume and save its information in local storage
          // in order to be able to recover the metadata in case of
          // restarts, system crashes, etc.
          chrome.fileSystem.getDisplayPath(item.entry, function(displayPath) {
            volumes[displayPath] = new Volume(item.entry, metadata);
            chrome.fileSystemProvider.mount(
                {fileSystemId: displayPath, displayName: item.entry.name},
                function() { saveState(); },
                function() { console.error('Failed to mount.'); });
          });
        },
        function(error) {
          console.error(error);
        });
  });
});

// Event called on a profile startup.
chrome.runtime.onStartup.addListener(function () {
  chrome.storage.local.get(['state'], function(result) {
    // Nothing to change.
    if (!result.state)
      return;

    // Remove files opened before the profile shutdown from the local storage.
    for (var volumeId in result.state) {
      result.state[volumeId].openedFiles = {};
    }
    chrome.storage.local.set({state: result.state});
  });
});

// Save the state before suspending the event page, so we can resume it
// once new events arrive.
chrome.runtime.onSuspend.addListener(function() {
  saveState();
});

chrome.fileSystemProvider.onUnmountRequested.addListener(
    onUnmountRequested);
chrome.fileSystemProvider.onGetMetadataRequested.addListener(
    onGetMetadataRequested);
chrome.fileSystemProvider.onReadDirectoryRequested.addListener(
    onReadDirectoryRequested);
chrome.fileSystemProvider.onOpenFileRequested.addListener(
    onOpenFileRequested);
chrome.fileSystemProvider.onCloseFileRequested.addListener(
    onCloseFileRequested);
chrome.fileSystemProvider.onReadFileRequested.addListener(
    onReadFileRequested);
