// Copyright 2014 The Chromium OS 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';

/**
 * The main namespace for the extension.
 * @namespace
 */
unpacker.app = {
  /**
   * The key used by chrome.storage.local to save and restore the volumes state.
   * @const {string}
   */
  STORAGE_KEY: 'state',

  /**
   * The default id for the NaCl module.
   * @const {string}
   */
  DEFAULT_MODULE_ID: 'nacl_module',

  /**
   * Time in milliseconds before the notification about mounting is shown.
   * @const {number}
   */
  MOUNTING_NOTIFICATION_DELAY: 1000,

  /**
   * The default filename for .nmf file.
   * This value must not be const because it is overwritten in tests.
   * @type {string}
   */
  DEFAULT_MODULE_NMF: 'module.nmf',

  /**
   * The default MIME type for .nmf file.
   * @const {string}
   */
  DEFAULT_MODULE_TYPE: 'application/x-pnacl',

  /**
   * Multiple volumes can be opened at the same time.
   * @type {!Object<!unpacker.types.FileSystemId, !unpacker.Volume>}
   */
  volumes: {},

  /**
   * Each "Pack with" request from Files app creates a new compressor.
   * Thus, multiple compressors can exist at the same time.
   * @type {!Object<!unpacker.types.CompressorId, !unpacker.Compressor>}
   */
  compressors: {},

  /**
   * A map with promises of loading a volume's metadata from NaCl.
   * Any call from fileSystemProvider API should work only on valid metadata.
   * These promises ensure that the fileSystemProvider API calls wait for the
   * metatada load.
   * @type {!Object<!unpacker.types.FileSystemId, !Promise>}
   */
  volumeLoadedPromises: {},

  /**
   * A Promise used to postpone all calls to fileSystemProvider API after
   * the NaCl module loads.
   * @type {?Promise}
   */
  moduleLoadedPromise: null,

  /**
   * The NaCl module containing the logic for decompressing archives.
   * @type {?Object}
   */
  naclModule: null,

  /**
   * The number of mount process in progress. NaCL module is unloaded if
   * app.unpacker.volumes is empty and this counter is 0. This is incremented
   * when a mounting process starts and decremented when it ends.
   * @type {number}
   */
  mountProcessCounter: 0,

  /**
   * Function called on receiving a message from NaCl module. Registered by
   * common.js.
   * Process pack message by getting compressor and passing the message to it.
   * @param {!Object} message The message received from NaCl module.
   * @param {!unpacker.request.Operation} operation
   * @private
   */
  handlePackMessage_: function(message, operation) {
    var compressorId = message.data[unpacker.request.Key.COMPRESSOR_ID];
    console.assert(compressorId, 'No NaCl compressor id.');

    var compressor = unpacker.app.compressors[compressorId];
    if (!compressor) {
      console.error('No compressor for compressor id: ' + compressorId + '.');
      return;
    }
    compressor.processMessage(message.data, operation);
  },

  /**
   * Process unpack message by getting volume and passing the message to it.
   * @param {!Object} message The message received from NaCl module.
   * @param {!unpacker.request.Operation} operation
   * @private
   */
  handleUnpackMessage_: function(message, operation) {
    var fileSystemId = message.data[unpacker.request.Key.FILE_SYSTEM_ID];
    console.assert(fileSystemId, 'No NaCl file system id.');

    var requestId = message.data[unpacker.request.Key.REQUEST_ID];
    console.assert(!!requestId, 'No NaCl request id.');

    var volume = unpacker.app.volumes[fileSystemId];
    if (!volume) {
      // The volume is gone, which can happen.
      console.info('No volume for: ' + fileSystemId + '.');
      return;
    }

    volume.decompressor.processMessage(message.data, operation,
                                       Number(requestId));
  },

  /**
   * Function called on receiving a message from NaCl module. Registered by
   * common.js.
   * @param {!Object} message The message received from NaCl module.
   * @private
   */
  handleMessage_: function(message) {
    // Get mandatory fields in a message.
    var operation = message.data[unpacker.request.Key.OPERATION];
    console.assert(operation != undefined,  // Operation can be 0.
                   'No NaCl operation: ' + operation + '.');

    // Assign the message to either module.
    if (unpacker.request.isPackRequest(operation))
      unpacker.app.handlePackMessage_(message, operation);
    else
      unpacker.app.handleUnpackMessage_(message, operation);
  },

  /**
   * Saves state in case of restarts, event page suspend, crashes, etc.
   * @param {!Array<!unpacker.types.FileSystemId>} fileSystemIdsArray
   * @private
   */
  saveState_: function(fileSystemIdsArray) {
    chrome.storage.local.get([unpacker.app.STORAGE_KEY], function(result) {
      if (!result[unpacker.app.STORAGE_KEY])  // First save state call.
        result[unpacker.app.STORAGE_KEY] = {};

      // Overwrite state only for the volumes that have their file system id
      // present in the input array. Leave the rest of the volumes state
      // untouched.
      fileSystemIdsArray.forEach(function(fileSystemId) {
        var entryId = chrome.fileSystem.retainEntry(
            unpacker.app.volumes[fileSystemId].entry);
        result[unpacker.app.STORAGE_KEY][fileSystemId] = {
          entryId: entryId,
          passphrase: unpacker.app.volumes[fileSystemId]
                          .decompressor.passphraseManager.rememberedPassphrase
        };
      });

      chrome.storage.local.set(result);
    });
  },

  /**
   * Removes state from local storage for a single volume.
   * @param {!unpacker.types.FileSystemId} fileSystemId
   */
  removeState_: function(fileSystemId) {
    chrome.storage.local.get([unpacker.app.STORAGE_KEY], function(result) {
      console.assert(result[unpacker.app.STORAGE_KEY] &&
                         result[unpacker.app.STORAGE_KEY][fileSystemId],
                     'Should call removeState_ only for file systems that ',
                     'have previously called saveState_.');

      delete result[unpacker.app.STORAGE_KEY][fileSystemId];
      chrome.storage.local.set(result);
    });
  },

  /**
   * Restores archive's entry and opened files for the passed file system id.
   * @param {!unpacker.types.FileSystemId} fileSystemId
   * @return {!Promise<!Object>} Promise fulfilled with the entry and list of
   *     opened files.
   * @private
   */
  restoreVolumeState_: function(fileSystemId) {
    return new Promise(function(fulfill, reject) {
      chrome.storage.local.get([unpacker.app.STORAGE_KEY], function(result) {
        if (!result[unpacker.app.STORAGE_KEY]) {
          reject('FAILED');
          return;
        }

        var volumeState = result[unpacker.app.STORAGE_KEY][fileSystemId];
        if (!volumeState) {
          console.error('No state for: ' + fileSystemId + '.');
          reject('FAILED');
          return;
        }

        chrome.fileSystem.restoreEntry(volumeState.entryId, function(entry) {
          if (chrome.runtime.lastError) {
            console.error('Restore entry error for <', fileSystemId, '>: ' +
                          chrome.runtime.lastError.message);
            reject('FAILED');
            return;
          }
          fulfill({
            entry: entry,
            passphrase: volumeState.passphrase
          });
        });
      });
    });
  },

  /**
   * Creates a volume and loads its metadata from NaCl.
   * @param {!unpacker.types.FileSystemId} fileSystemId
   * @param {!Entry} entry The volume's archive entry.
   * @param {!Object<!unpacker.types.RequestId,
   *                 !unpacker.types.OpenFileRequestedOptions>}
   *     openedFiles Previously opened files before a suspend.
   * @param {string} passphrase Previously used passphrase before a suspend.
   * @return {!Promise} Promise fulfilled on success and rejected on failure.
   * @private
   */
  loadVolume_: function(fileSystemId, entry, openedFiles, passphrase) {
    return new Promise(function(fulfill, reject) {
      entry.file(function(file) {
        // File is a Blob object, so it's ok to construct the Decompressor
        // directly with it.
        var passphraseManager = new unpacker.PassphraseManager(passphrase);
        console.assert(unpacker.app.naclModule,
                       'The NaCL module should have already been defined.');
        var decompressor = new unpacker.Decompressor(
            /** @type {!Object} */ (unpacker.app.naclModule),
            fileSystemId, file, passphraseManager);
        var volume = new unpacker.Volume(decompressor, entry);

        var onLoadVolumeSuccess = function() {
          if (Object.keys(openedFiles).length == 0) {
            fulfill();
            return;
          }

          // Restore opened files on NaCl side.
          var openFilePromises = [];
          for (var key in openedFiles) {
            // 'key' is always a number but JS compiler complains that it is
            // a string.
            var openRequestId = Number(key);
            var options =
                /** @type {!unpacker.types.OpenFileRequestedOptions} */
                (openedFiles[openRequestId]);
            openFilePromises.push(new Promise(function(resolve, reject) {
              volume.onOpenFileRequested(options, resolve, reject);
            }));
          }

          Promise.all(openFilePromises).then(fulfill, reject);
        };

        unpacker.app.volumes[fileSystemId] = volume;
        volume.initialize(onLoadVolumeSuccess, reject);
      }, function(error) {
        reject('FAILED');
      });
    });
  },

  /**
   * Restores a volume mounted previously to a suspend / restart. In case of
   * failure of the load promise for fileSystemId, the corresponding volume is
   * forcely unmounted.
   * @param {!unpacker.types.FileSystemId} fileSystemId
   * @return {!Promise} A promise that restores state and loads volume.
   * @private
   */
  restoreSingleVolume_: function(fileSystemId) {
    // Load volume after restart / suspend page event.
    return unpacker.app.restoreVolumeState_(fileSystemId)
        .then(function(state) {
          return new Promise(function(fulfill, reject) {
            // Check if the file system is compatible with this version of the
            // ZIP unpacker.
            // TODO(mtomasz): Implement remounting instead of unmounting.
            chrome.fileSystemProvider.get(fileSystemId, function(fileSystem) {
              if (chrome.runtime.lastError) {
                console.error(chrome.runtime.lastError.name);
                reject('FAILED');
                return;
              }
              if (!fileSystem || fileSystem.openedFilesLimit != 1) {
                console.error('No compatible mounted file system found.');
                reject('FAILED');
                return;
              }
              fulfill({state: state, fileSystem: fileSystem});
            });
          });
        })
        .then(function(stateWithFileSystem) {
          var openedFilesOptions = {};
          stateWithFileSystem.fileSystem.openedFiles.forEach(function(
              openedFile) {
            openedFilesOptions[openedFile.openRequestId] = {
              fileSystemId: fileSystemId,
              requestId: openedFile.openRequestId,
              mode: openedFile.mode,
              filePath: openedFile.filePath
            };
          });
          return unpacker.app.loadVolume_(
              fileSystemId, stateWithFileSystem.state.entry, openedFilesOptions,
              stateWithFileSystem.state.passphrase);
        })
        .catch(function(error) {
          console.error(error.stack || error);
          // Force unmount in case restore failed. All resources related to the
          // volume will be cleanup from both memory and local storage.
          // TODO(523195): Show a notification that the source file is gone.
          return unpacker.app.unmountVolume(fileSystemId, true)
              .then(function() { return Promise.reject('FAILED'); });
        });
  },

  /**
   * Ensures a volume is loaded by returning its corresponding loaded promise
   * from unpacker.app.volumeLoadedPromises. In case there is no such promise,
   * then this is a call after suspend / restart and a new volume loaded promise
   * that restores state is returned.
   * @param {!unpacker.types.FileSystemId} fileSystemId
   * @return {!Promise} The loading volume promise.
   * @private
   */
  ensureVolumeLoaded_: function(fileSystemId) {
    // Increment the counter so that the NaCl module won't be unloaded until
    // the mounting process ends.
    unpacker.app.mountProcessCounter++;
    // Create a promise to load the NaCL module.
    if (!unpacker.app.moduleLoadedPromise)
      unpacker.app.loadNaclModule(unpacker.app.DEFAULT_MODULE_NMF,
                                  unpacker.app.DEFAULT_MODULE_TYPE);

    return unpacker.app.moduleLoadedPromise.then(function() {
      // In case there is no volume promise for fileSystemId then we
      // received a call after restart / suspend as load promises are
      // created on launched. In this case we will restore volume state
      // from local storage and create a new load promise.
      if (!unpacker.app.volumeLoadedPromises[fileSystemId]) {
        unpacker.app.volumeLoadedPromises[fileSystemId] =
            unpacker.app.restoreSingleVolume_(fileSystemId);
      }

      // Decrement the counter when the mounting process ends.
      unpacker.app.volumeLoadedPromises[fileSystemId].then(function() {
        unpacker.app.mountProcessCounter--;
      }).catch(function(error) {
        unpacker.app.mountProcessCounter--;
      });

      return unpacker.app.volumeLoadedPromises[fileSystemId];
    });
  },

  /**
   * @return {boolean} True if NaCl module is loaded.
   */
  naclModuleIsLoaded: function() { return !!unpacker.app.naclModule; },

  /**
   * Loads the NaCl module.
   * @param {string} pathToConfigureFile Path to the module's configuration
   *     file, which should be a .nmf file.
   * @param {string} mimeType The mime type for the NaCl executable.
   * @param {string=} opt_moduleId The NaCl module id. Necessary for testing
   *     purposes.
   */
  loadNaclModule: function(pathToConfigureFile, mimeType, opt_moduleId) {
    unpacker.app.moduleLoadedPromise = new Promise(function(fulfill) {
      var moduleId =
          opt_moduleId ? opt_moduleId : unpacker.app.DEFAULT_MODULE_ID;
      var elementDiv = document.createElement('div');

      // Promise fulfills only after NaCl module has been loaded.
      elementDiv.addEventListener('load', function() {
        // Since the first load of the NaCL module is slow, the module is loaded
        // once in background.js in advance. If there is no mounted volume and
        // ongoing mounting process, the module is just unloaded. This is the
        // workaround for crbug.com/699930.
        if (Object.keys(unpacker.app.volumes).length === 0 &&
            unpacker.app.mountProcessCounter === 0) {
          elementDiv.parentNode.removeChild(elementDiv);
          // This is necessary for tests.
          fulfill();
          unpacker.app.moduleLoadedPromise = null;
          return;
        }
        unpacker.app.naclModule = document.getElementById(moduleId);
        fulfill();
      }, true);

      elementDiv.addEventListener('message', unpacker.app.handleMessage_, true);

      var elementEmbed = document.createElement('embed');
      elementEmbed.id = moduleId;
      elementEmbed.style.width = 0;
      elementEmbed.style.height = 0;
      elementEmbed.src = pathToConfigureFile;
      elementEmbed.type = mimeType;
      elementDiv.appendChild(elementEmbed);

      document.body.appendChild(elementDiv);
      // Request the offsetTop property to force a relayout. As of Apr 10, 2014
      // this is needed if the module is being loaded on a Chrome App's
      // background page (see crbug.com/350445).
      /** @suppress {suspiciousCode} */ elementEmbed.offsetTop;
    });
  },

  /**
   * Unloads the NaCl module.
   */
  unloadNaclModule: function() {
    var naclModuleParentNode = unpacker.app.naclModule.parentNode;
    naclModuleParentNode.parentNode.removeChild(naclModuleParentNode);
    unpacker.app.naclModule = null;
    unpacker.app.moduleLoadedPromise = null;
  },

  /**
   * Cleans up the resources for a volume, except for the local storage. If
   * necessary that can be done using unpacker.app.removeState_.
   * @param {!unpacker.types.FileSystemId} fileSystemId
   */
  cleanupVolume: function(fileSystemId) {
    delete unpacker.app.volumes[fileSystemId];
    // Allow mount after clean.
    delete unpacker.app.volumeLoadedPromises[fileSystemId];

    if (Object.keys(unpacker.app.volumes).length === 0 &&
        unpacker.app.mountProcessCounter === 0) {
      unpacker.app.unloadNaclModule();
    } else {
      unpacker.app.naclModule.postMessage(
          unpacker.request.createCloseVolumeRequest(fileSystemId));
    }
  },

  /**
   * Cleans up the resources for a compressor.
   * @param {!unpacker.types.CompressorId} compressorId
   * @param {boolean} hasError
   */
  cleanupCompressor: function(compressorId, hasError) {
    var compressor = unpacker.app.compressors[compressorId];
    if (!compressor) {
      console.error('No compressor for: compressor id' + compressorId + '.');
      return;
    }

    unpacker.app.mountProcessCounter--;
    if (Object.keys(unpacker.app.volumes).length === 0 &&
        unpacker.app.mountProcessCounter === 0) {
      unpacker.app.unloadNaclModule();
    } else {
      // Request libarchive to abort any ongoing process and release resources.
      // The argument indicates whether an error occurred or not.
      if (hasError)
        compressor.sendCloseArchiveRequest(hasError);
    }

    // Delete the archive file if it exists.
    if (compressor.archiveFileEntry)
      compressor.archiveFileEntry.remove();

    delete unpacker.app.compressors[compressorId];
  },

  /**
   * Unmounts a volume and removes any resources related to the volume from both
   * the extension and the local storage state.
   * @param {!unpacker.types.FileSystemId} fileSystemId
   * @param {boolean=} opt_forceUnmount True if unmount should be forced even if
   *     volume might be in use, or is not restored yet.
   * @return {!Promise} A promise that fulfills if volume is unmounted or
   *     rejects with ProviderError in case of any errors.
   */
  unmountVolume: function(fileSystemId, opt_forceUnmount) {
    return new Promise(function(fulfill, reject) {
      var volume = unpacker.app.volumes[fileSystemId];
      console.assert(volume || opt_forceUnmount,
                     'Unmount that is not forced must not be called for ',
                     'volumes that are not restored.');

      if (!opt_forceUnmount && volume.inUse()) {
        reject('IN_USE');
        return;
      }

      var options = {
        fileSystemId: fileSystemId
      };
      chrome.fileSystemProvider.unmount(options, function() {
        if (chrome.runtime.lastError) {
          console.error('Unmount error: ' + chrome.runtime.lastError.message +
              '.');
          reject('FAILED');
          return;
        }

        // In case of forced unmount volume can be undefined due to not being
        // restored. An unmount that is not forced will be called only after
        // restoring state. In the case of forced unmount when volume is not
        // restored, we will not do a normal cleanup, but just remove the load
        // volume promise to allow further mounts.
        if (opt_forceUnmount)
          delete unpacker.app.volumeLoadedPromises[fileSystemId];
        else
          unpacker.app.cleanupVolume(fileSystemId);

        // Remove volume from local storage.
        unpacker.app.removeState_(fileSystemId);
        fulfill();
      });
    });
  },

  /**
   * Handles an unmount request received from File System Provider API.
   * @param {!unpacker.types.UnmountRequestedOptions} options
   * @param {function()} onSuccess Callback to execute on success.
   * @param {function(!ProviderError)} onError Callback to execute on error.
   */
  onUnmountRequested: function(options, onSuccess, onError) {
    unpacker.app.ensureVolumeLoaded_(options.fileSystemId)
        .then(function() {
          return unpacker.app.unmountVolume(options.fileSystemId);
        })
        .then(onSuccess)
        .catch(/** @type {function(*)} */ (onError));
  },

  /**
   * Obtains metadata about a file system entry.
   * @param {!unpacker.types.GetMetadataRequestedOptions} options
   * @param {function(!EntryMetadata)} onSuccess Callback to execute on success.
   *     The parameter is the EntryMetadata obtained by this function.
   * @param {function(!ProviderError)} onError Callback to execute on error.
   */
  onGetMetadataRequested: function(options, onSuccess, onError) {
    unpacker.app.ensureVolumeLoaded_(options.fileSystemId)
        .then(function() {
          unpacker.app.volumes[options.fileSystemId].onGetMetadataRequested(
              options, onSuccess, onError);
        })
        .catch(/** @type {function(*)} */ (onError));
  },

  /**
   * Reads a directory entries.
   * @param {!unpacker.types.ReadDirectoryRequestedOptions} options
   * @param {function(!Array<!EntryMetadata>, boolean)} onSuccess Callback to
   *     execute on success. The first parameter is an array with directory
   *     entries. The second parameter is 'hasMore', and if it's set to true,
   *     then onSuccess must be called again with the next directory entries.
   * @param {function(!ProviderError)} onError Callback to execute on error.
   */
  onReadDirectoryRequested: function(options, onSuccess, onError) {
    unpacker.app.ensureVolumeLoaded_(options.fileSystemId)
        .then(function() {
          unpacker.app.volumes[options.fileSystemId].onReadDirectoryRequested(
              options, onSuccess, onError);
        })
        .catch(/** @type {function(*)} */ (onError));
  },

  /**
   * Opens a file for read or write.
   * @param {!unpacker.types.OpenFileRequestedOptions} options
   * @param {function()} onSuccess Callback to execute on success.
   * @param {function(!ProviderError)} onError Callback to execute on error.
   */
  onOpenFileRequested: function(options, onSuccess, onError) {
    unpacker.app.ensureVolumeLoaded_(options.fileSystemId)
        .then(function() {
          unpacker.app.volumes[options.fileSystemId].onOpenFileRequested(
              options, onSuccess, onError);
        })
        .catch(/** @type {function(*)} */ (onError));
  },

  /**
   * Closes a file identified by options.openRequestId.
   * @param {!unpacker.types.CloseFileRequestedOptions} options
   * @param {function()} onSuccess Callback to execute on success.
   * @param {function(!ProviderError)} onError Callback to execute on error.
   */
  onCloseFileRequested: function(options, onSuccess, onError) {
    unpacker.app.ensureVolumeLoaded_(options.fileSystemId)
        .then(function() {
          unpacker.app.volumes[options.fileSystemId].onCloseFileRequested(
              options, onSuccess, onError);
        })
        .catch(/** @type {function(*)} */ (onError));
  },

  /**
   * Reads the contents of a file identified by options.openRequestId.
   * @param {!unpacker.types.ReadFileRequestedOptions} options
   * @param {function(!ArrayBuffer, boolean)} onSuccess Callback to execute on
   *     success. The first parameter is the read data and the second parameter
   *     is 'hasMore'. If it's set to true, then onSuccess must be called again
   *     with the next data to read.
   * @param {function(!ProviderError)} onError Callback to execute on error.
   */
  onReadFileRequested: function(options, onSuccess, onError) {
    unpacker.app.ensureVolumeLoaded_(options.fileSystemId)
        .then(function() {
          unpacker.app.volumes[options.fileSystemId].onReadFileRequested(
              options, onSuccess, onError);
        })
        .catch(/** @type {function(*)} */ (onError));
  },

  /**
   * Creates a new compressor and compresses entries.
   * @param {!Object} launchData
   */
  onLaunchedWithPack: function(launchData) {
    unpacker.app.mountProcessCounter++;

    // Create a promise to load the NaCL module.
    if (!unpacker.app.moduleLoadedPromise) {
      unpacker.app.loadNaclModule(unpacker.app.DEFAULT_MODULE_NMF,
                                  unpacker.app.DEFAULT_MODULE_TYPE);
    }

    unpacker.app.moduleLoadedPromise
        .then(function() {
          var compressor = new unpacker.Compressor(
              /** @type {!Object} */ (unpacker.app.naclModule),
             launchData.items);

          var compressorId = compressor.getCompressorId();

          unpacker.app.compressors[compressorId] = compressor;

          // TODO(takise): Error messages have not been prepared yet for timer
          // and error processing.

          // If packing takes significant amount of time, then show a
          // notification about packing in progress.
          // var deferredNotificationTimer = setTimeout(function() {
          //   chrome.notifications.create(compressorId.toString(), {
          //     type: 'basic',
          //     iconUrl: chrome.runtime.getManifest().icons[128],
          //     title: entry.name,
          //     message: chrome.i18n.getMessage('packingMessage'),
          //   }, function() {});
          // }, unpacker.app.PACKING_NOTIFICATION_DELAY);

          var onError = function(compressorId) {
            // clearTimeout(deferredNotificationTimer);
            // console.error('Packing error: ' + error.message + '.');
            // chrome.notifications.create(compressorId.toString(), {
            //   type: 'basic',
            //   iconUrl: chrome.runtime.getManifest().icons[128],
            //   title: entry.name,
            //   message: chrome.i18n.getMessage('packingErrorMessage')
            // }, function() {});
            unpacker.app.cleanupCompressor(compressorId, true /* hasError */);
          };

          var onSuccess = function(compressorId) {
            // clearTimeout(deferredNotificationTimer);
            // chrome.notifications.clear(compressorId.toString(),
            //     function() {});
            unpacker.app.cleanupCompressor(compressorId, false /* hasError */);
          };

          compressor.compress(onSuccess, onError);
        });
  },

  /**
   * Creates a volume for every opened file with the extension or mime type
   * declared in the manifest file.
   * @param {!Object} launchData
   * @param {function(string)=} opt_onSuccess Callback to execute in case a
   *     volume was loaded successfully. Has one parameter, which is the file
   *     system id of the loaded volume. Can be called multiple times, depending
   *     on how many volumes must be loaded.
   * @param {function(string)=} opt_onError Callback to execute in case of
   *     failure when loading a volume. Has one parameter, which is the file
   *     system id of the volume that failed to load. Can be called multiple
   *     times, depending on how many volumes must be loaded.
   */
  onLaunchedWithUnpack: function(launchData, opt_onSuccess, opt_onError) {
    // Increment the counter that indicates the number of ongoing mouot process.
    unpacker.app.mountProcessCounter++;

    // Create a promise to load the NaCL module.
    if (!unpacker.app.moduleLoadedPromise) {
      unpacker.app.loadNaclModule(unpacker.app.DEFAULT_MODULE_NMF,
                                  unpacker.app.DEFAULT_MODULE_TYPE);
    }

    unpacker.app.moduleLoadedPromise
        .then(function() {
          unpacker.app.mountProcessCounter--;
          launchData.items.forEach(function(item) {
            unpacker.app.mountProcessCounter++;
            chrome.fileSystem.getDisplayPath(item.entry, function(
                                                             entry,
                                                             fileSystemId) {
              // If loading takes significant amount of time, then show a
              // notification about scanning in progress.
              var deferredNotificationTimer = setTimeout(function() {
                chrome.notifications.create(fileSystemId, {
                  type: 'basic',
                  iconUrl: chrome.runtime.getManifest().icons[128],
                  title: entry.name,
                  message: chrome.i18n.getMessage('mountingMessage'),
                }, function() {});
              }, unpacker.app.MOUNTING_NOTIFICATION_DELAY);

              var onError = function(error, fileSystemId) {
                clearTimeout(deferredNotificationTimer);
                console.error('Mount error: ' + error.message + '.');
                // Decrement the counter that indicates the number of ongoing
                // mount process.
                unpacker.app.mountProcessCounter--;
                if (error.message === 'EXISTS') {
                  if (opt_onError)
                    opt_onError(fileSystemId);
                  return;
                }
                chrome.notifications.create(fileSystemId, {
                  type: 'basic',
                  iconUrl: chrome.runtime.getManifest().icons[128],
                  title: entry.name,
                  message: chrome.i18n.getMessage('otherErrorMessage')
                }, function() {});
                if (opt_onError)
                  opt_onError(fileSystemId);
                // Cleanup volume resources in order to allow future attempts
                // to mount the volume. The volume can't be cleaned up in
                // case of 'EXIST' because we should not clean the other
                // already mounted volume.
                unpacker.app.cleanupVolume(fileSystemId);
              };

              var onSuccess = function(fileSystemId) {
                clearTimeout(deferredNotificationTimer);
                chrome.notifications.clear(fileSystemId, function() {});
                // Decrement the counter that indicates the number of ongoing
                // mount process.
                unpacker.app.mountProcessCounter--;
                if (opt_onSuccess)
                  opt_onSuccess(fileSystemId);
              };

              var loadPromise = unpacker.app.loadVolume_(
                  fileSystemId, entry, {}, '' /* passphrase */);
              loadPromise.then(function() {
                // 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.
                const mountOptions = {
                  fileSystemId: fileSystemId,
                  displayName: entry.name,
                  openedFilesLimit: 1
                };
                if (unpacker.app.getChromeMajorVersion_() >= 64)
                  mountOptions.persistent = false;
                chrome.fileSystemProvider.mount(mountOptions, function() {
                  if (chrome.runtime.lastError) {
                    onError(chrome.runtime.lastError, fileSystemId);
                    return;
                  }
                  // Save state so in case of restarts we are able to correctly
                  // get the archive's metadata.
                  unpacker.app.saveState_([fileSystemId]);
                  onSuccess(fileSystemId);
                });
              }).catch(function(error) {
                onError(error.stack || error, fileSystemId);
                return Promise.reject(error);
              });

              unpacker.app.volumeLoadedPromises[fileSystemId] = loadPromise;
            }.bind(null, item.entry));
          });
        })
        .catch(function(error) { console.error(error.stack || error); });
  },

  /**
   * Fired when this extension is launched.
   * Calls a module designated by launchData.id.
   * Currently, Verbs API does not support "unpack" option. Thus, any launchData
   * that does not have "pack" as id is regarded as unpack for now.
   * @param {!Object} launchData
   * @param {function(string)=} opt_onSuccess
   * @param {function(string)=} opt_onError
   */
  onLaunched: function(launchData, opt_onSuccess, opt_onError) {
    if (launchData.items == null) {
      // The user tried to launch us directly.
      console.log('Ignoring launch request w/out items field', {launchData});
      return;
    }

    if (launchData.id === "pack")
      unpacker.app.onLaunchedWithPack(launchData);
    else
      unpacker.app.onLaunchedWithUnpack(launchData, opt_onSuccess, opt_onError);
  },

  /**
   * Saves the state before suspending the event page, so we can resume it
   * once new events arrive.
   */
  onSuspend: function() {
    unpacker.app.saveState_(Object.keys(unpacker.app.volumes));
  },

  /**
   * Gets the major version number of Chrome currently running.
   * @private
   * @return {number}
   */
  getChromeMajorVersion_: function() {
    const r = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)/);
    console.assert(r, 'Failed to identify Chrome version.');
    return parseInt(r[2]);
  }
};
