// 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';

/**
 * A class that takes care of communication between NaCl and archive volume.
 * Its job is to handle communication with the naclModule.
 * @constructor
 * @param {!Object} naclModule The nacl module with which the decompressor
 *     communicates.
 * @param {!unpacker.types.FileSystemId} fileSystemId The file system id of for
 *     the archive volume to decompress.
 * @param {!Blob} blob The correspondent file blob for fileSystemId.
 * @param {!unpacker.PassphraseManager} passphraseManager Passphrase manager.
 */
unpacker.Decompressor = function(naclModule, fileSystemId, blob,
                                 passphraseManager) {
  /**
   * @private {!Object}
   * @const
   */
  this.naclModule_ = naclModule;

  /**
   * @private {!unpacker.types.FileSystemId}
   * @const
   */
  this.fileSystemId_ = fileSystemId;

  /**
   * @private {!Blob}
   * @const
   */
  this.blob_ = blob;

  /**
   * @public {!unpacker.PassphraseManager}
   * @const
   */
  this.passphraseManager = passphraseManager;

  /**
   * Requests in progress. No need to save them onSuspend for now as metadata
   * reads are restarted from start.
   * @public {!Object<!unpacker.types.RequestId, !Object>}
   * @const
   */
  this.requestsInProgress = {};
};

/**
 * @return {boolean} True if there is any request in progress.
 */
unpacker.Decompressor.prototype.hasRequestsInProgress = function() {
  return Object.keys(this.requestsInProgress).length > 0;
};

/**
 * Sends a request to NaCl and mark it as a request in progress. onSuccess and
 * onError are the callbacks used when receiving an answer from NaCl.
 * @param {!unpacker.types.RequestId} requestId The operation request id, which
 *     should be unique per every volume.
 * @param {function(...)} onSuccess Callback to execute on success.
 * @param {function(!ProviderError)} onError Callback to execute on error.
 * @param {!Object} naclRequest A request that must be sent to NaCl using
 *     postMessage.
 * @private
 */
unpacker.Decompressor.prototype.addRequest_ = function(requestId, onSuccess,
                                                       onError, naclRequest) {
  console.assert(!this.requestsInProgress[requestId],
                 'There is already a request with the id ' + requestId + '.');

  this.requestsInProgress[requestId] = {
    onSuccess: onSuccess,
    onError: onError
  };

  this.naclModule_.postMessage(naclRequest);
};

/**
 * Creates a request for reading metadata.
 * @param {!unpacker.types.RequestId} requestId
 * @param {string} encoding Default encoding for the archive's headers.
 * @param {function(!Object<string, !Object>)} onSuccess Callback to execute
 *     once the metadata is obtained from NaCl. It has one parameter, which is
 *     the metadata itself. The metadata has as key the full path to an entry
 *     and as value information about the entry.
 * @param {function(!ProviderError)} onError Callback to execute on error.
 */
unpacker.Decompressor.prototype.readMetadata = function(requestId, encoding,
                                                        onSuccess, onError) {
  this.addRequest_(
      requestId, onSuccess, onError,
      unpacker.request.createReadMetadataRequest(this.fileSystemId_, requestId,
                                                 encoding, this.blob_.size));
};

/**
 * Sends an open file request to NaCl.
 * @param {!unpacker.types.RequestId} requestId
 * @param {number} index Index of the file in the header list.
 * @param {string} encoding Default encoding for the archive's headers.
 * @param {function()} onSuccess Callback to execute on successful open.
 * @param {function(!ProviderError)} onError Callback to execute on error.
 */
unpacker.Decompressor.prototype.openFile = function(requestId, index, encoding,
                                                    onSuccess, onError) {
  this.addRequest_(
      requestId, onSuccess, onError,
      unpacker.request.createOpenFileRequest(this.fileSystemId_, requestId,
                                             index, encoding, this.blob_.size));
};

/**
 * Sends a close file request to NaCl.
 * @param {!unpacker.types.RequestId} requestId
 * @param {!unpacker.types.RequestId} openRequestId The request id of the
 *     corresponding open file operation for the file to close.
 * @param {function()} onSuccess Callback to execute on successful open.
 * @param {function(!ProviderError)} onError Callback to execute on error.
 */
unpacker.Decompressor.prototype.closeFile = function(requestId, openRequestId,
                                                     onSuccess, onError) {
  this.addRequest_(requestId, onSuccess, onError,
                   unpacker.request.createCloseFileRequest(
                       this.fileSystemId_, requestId, openRequestId));
};

/**
 * Sends a read file request to NaCl.
 * @param {!unpacker.types.RequestId} requestId
 * @param {!unpacker.types.RequestId} openRequestId The request id of the
 *     corresponding open file operation for the file to read.
 * @param {number} offset The offset from where read operation should start.
 * @param {number} length The number of bytes to read.
 * @param {function(!ArrayBuffer, boolean)} onSuccess Callback to execute on
 *     success.
 * @param {function(!ProviderError)} onError Callback to execute on error.
 */
unpacker.Decompressor.prototype.readFile = function(
    requestId, openRequestId, offset, length, onSuccess, onError) {
  this.addRequest_(
      requestId, onSuccess, onError,
      unpacker.request.createReadFileRequest(this.fileSystemId_, requestId,
                                             openRequestId, offset, length));
};

/**
 * Processes messages from NaCl module.
 * @param {!Object} data The data contained in the message from NaCl. Its
 *     types depend on the operation of the request.
 * @param {!unpacker.request.Operation} operation An operation from request.js.
 * @param {number} requestId The request id, which should be unique per every
 *     volume.
 */
unpacker.Decompressor.prototype.processMessage = function(data, operation,
                                                          requestId) {
  // Create a request reference for asynchronous calls as sometimes we delete
  // some requestsInProgress from this.requestsInProgress.
  var requestInProgress = this.requestsInProgress[requestId];
  console.assert(requestInProgress, 'No request with id <' + requestId +
                 '> for: ' + this.fileSystemId_ + '.');

  switch (operation) {
    case unpacker.request.Operation.READ_METADATA_DONE:
      var metadata = data[unpacker.request.Key.METADATA];
      console.assert(metadata, 'No metadata.');
      requestInProgress.onSuccess(metadata);
      break;

    case unpacker.request.Operation.READ_CHUNK:
      this.readChunk_(data, requestId);
      // this.requestsInProgress_[requestId] should be valid as long as NaCL
      // can still make READ_CHUNK requests.
      return;

    case unpacker.request.Operation.READ_PASSPHRASE:
      this.readPassphrase_(data, requestId);
      // this.requestsInProgress_[requestId] should be valid as long as NaCL
      // can still make READ_PASSPHRASE requests.
      return;

    case unpacker.request.Operation.OPEN_FILE_DONE:
      requestInProgress.onSuccess();
      // this.requestsInProgress_[requestId] should be valid until closing the
      // file so NaCL can make READ_CHUNK requests.
      return;

    case unpacker.request.Operation.CLOSE_FILE_DONE:
      var openRequestId = data[unpacker.request.Key.OPEN_REQUEST_ID];
      console.assert(openRequestId, 'No open request id.');

      openRequestId = Number(openRequestId);  // Received as string.
      delete this.requestsInProgress[openRequestId];
      requestInProgress.onSuccess();
      break;

    case unpacker.request.Operation.READ_FILE_DONE:
      var buffer = data[unpacker.request.Key.READ_FILE_DATA];
      console.assert(buffer, 'No buffer for read file operation.');
      var hasMoreData = data[unpacker.request.Key.HAS_MORE_DATA];
      console.assert(buffer !== undefined,
                    'No HAS_MORE_DATA boolean value for file operation.');

      requestInProgress.onSuccess(buffer, hasMoreData /* Last call. */);
      if (hasMoreData)
        return;  // Do not delete requestInProgress.
      break;

    case unpacker.request.Operation.FILE_SYSTEM_ERROR:
      console.error('File system error for <' + this.fileSystemId_ + '>: ' +
                    data[unpacker.request.Key.ERROR]);  // The error contains
                                                        // the '.' at the end.
      requestInProgress.onError('FAILED');
      break;

    case unpacker.request.Operation.CONSOLE_LOG:
    case unpacker.request.Operation.CONSOLE_DEBUG:
      var src_file = data[unpacker.request.Key.SRC_FILE];
      var src_line = data[unpacker.request.Key.SRC_LINE];
      var src_func = data[unpacker.request.Key.SRC_FUNC];
      var msg = data[unpacker.request.Key.MESSAGE];
      var log = operation == unpacker.request.Operation.CONSOLE_LOG ?
                console.log : console.debug;
      log(src_file + ':' + src_func + ':' + src_line + ': ' + msg);
      break;

    default:
      console.error('Invalid NaCl operation: ' + operation + '.');
      requestInProgress.onError('FAILED');
  }
  delete this.requestsInProgress[requestId];
};

/**
 * Reads a chunk of data from this.blob_ for READ_CHUNK operation.
 * @param {!Object} data The data received from the NaCl module.
 * @param {number} requestId The request id, which should be unique per every
 *     volume.
 * @private
 */
unpacker.Decompressor.prototype.readChunk_ = function(data, requestId) {
  // Offset and length are received as strings. See request.js.
  var offset_str = data[unpacker.request.Key.OFFSET];
  var length_str = data[unpacker.request.Key.LENGTH];

  // Explicit check if offset is undefined as it can be 0.
  console.assert(offset_str !== undefined && !isNaN(offset_str) &&
                     Number(offset_str) >= 0 &&
                     Number(offset_str) < this.blob_.size,
                 'Invalid offset.');
  console.assert(length_str && !isNaN(length_str) && Number(length_str) > 0,
                 'Invalid length.');

  var offset = Number(offset_str);
  var length = Math.min(this.blob_.size - offset, Number(length_str));

  // Read a chunk from offset to offset + length.
  var blob = this.blob_.slice(offset, offset + length);
  var fileReader = new FileReader();

  fileReader.onload = function(event) {
    this.naclModule_.postMessage(unpacker.request.createReadChunkDoneResponse(
        this.fileSystemId_, requestId, event.target.result, offset));
  }.bind(this);

  fileReader.onerror = function(event) {
    console.error('Failed to read a chunk of data from the archive.');
    this.naclModule_.postMessage(unpacker.request.createReadChunkErrorResponse(
        this.fileSystemId_, requestId));
    // Reading from the source file failed. Assume that the file is gone and
    // unmount the archive.
    // TODO(523195): Show a notification that the source file is gone.
    unpacker.app.unmountVolume(this.fileSystemId_, true);
  }.bind(this);

  fileReader.readAsArrayBuffer(blob);
};

/**
 * Reads a passphrase from user input for READ_PASSPHRASE operation.
 * @param {!Object} data The data received from the NaCl module.
 * @param {number} requestId The request id, which should be unique per every
 *     volume.
 * @private
 */
unpacker.Decompressor.prototype.readPassphrase_ = function(data, requestId) {
  this.passphraseManager.getPassphrase()
      .then(function(passphrase) {
        this.naclModule_.postMessage(
            unpacker.request.createReadPassphraseDoneResponse(
                this.fileSystemId_, requestId, passphrase));
      }.bind(this))
      .catch(function(error) {
        console.error(error.stack || error);
        this.naclModule_.postMessage(
            unpacker.request.createReadPassphraseErrorResponse(
                this.fileSystemId_, requestId));
        // TODO(mtomasz): Instead of unmounting just let the current operation
        // fail and ask for password for another files. This is however
        // impossible for now due to a bug in libarchive.
        unpacker.app.unmountVolume(this.fileSystemId_, true);
      }.bind(this));
};
