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

/**
 * Converts a c/c++ time_t variable to Date.
 * @param {number} timestamp A c/c++ time_t variable.
 * @return {!Date}
 */
function DateFromTimeT(timestamp) {
  return new Date(1000 * timestamp);
}

/**
 * Corrects metadata entries fields in order for them to be sent to Files.app.
 * This function runs recursively for every entry in a directory.
 * @param {!Object<string, !EntryMetadata>} entryMetadata The metadata to
 *     correct.
 */
function correctMetadata(entryMetadata) {
  entryMetadata.index = parseInt(entryMetadata.index, 10);
  entryMetadata.size = parseInt(entryMetadata.size, 10);
  entryMetadata.modificationTime =
      DateFromTimeT(entryMetadata.modificationTime);
  if (entryMetadata.isDirectory) {
    console.assert(entryMetadata.entries,
        'The field "entries" is mandatory for dictionaries.');
    for (var entry in entryMetadata.entries) {
      correctMetadata(entryMetadata.entries[entry]);
    }
  }
}

/**
 * Defines a volume object that contains information about archives' contents
 * and performs operations on these contents.
 * @constructor
 * @param {!unpacker.Decompressor} decompressor The decompressor used to obtain
 *     data from archives.
 * @param {!Entry} entry The entry corresponding to the volume's archive.
 */
unpacker.Volume = function(decompressor, entry) {
  /**
   * Used for restoring the opened file entry after resuming the event page.
   * @type {!Entry}
   */
  this.entry = entry;

  /**
   * @type {!unpacker.Decompressor}
   */
  this.decompressor = decompressor;

  /**
   * The volume's metadata. The key is the full path to the file on this volume.
   * For more details see
   * https://developer.chrome.com/apps/fileSystemProvider#type-EntryMetadata
   * @type {?Object<string, !EntryMetadata>}
   */
  this.metadata = null;

  /**
   * A map with currently opened files. The key is a requestId value from the
   * openFileRequested event and the value is the open file options.
   * @type {!Object<!unpacker.types.RequestId,
   *                !unpacker.types.OpenFileRequestedOptions>}
   */
  this.openedFiles = {};

  /**
   * Default encoding set for this archive. If empty, then not known.
   * @type {string}
   */
  this.encoding =
      unpacker.Volume.ENCODING_TABLE[chrome.i18n.getUILanguage()] || '';

  /**
   * The default read metadata request id. -1 is ok as the request ids used by
   * flleSystemProvider are greater than 0.
   * @type {number}
   */
  this.DEFAULT_READ_METADATA_REQUEST_ID = -1;
};

/**
 * The default read metadata request id. -1 is ok as the request ids used by
 * flleSystemProvider are greater than 0.
 * @const {number}
 */
unpacker.Volume.DEFAULT_READ_METADATA_REQUEST_ID = -1;

/**
 * Map from language codes to default charset encodings.
 * @const {!Object<string, string>}
 */
unpacker.Volume.ENCODING_TABLE = {
  ar: 'CP1256',
  bg: 'CP1251',
  ca: 'CP1252',
  cs: 'CP1250',
  da: 'CP1252',
  de: 'CP1252',
  el: 'CP1253',
  en: 'CP1250',
  en_GB: 'CP1250',
  es: 'CP1252',
  es_419: 'CP1252',
  et: 'CP1257',
  fa: 'CP1256',
  fi: 'CP1252',
  fil: 'CP1252',
  fr: 'CP1252',
  he: 'CP1255',
  hi: 'UTF-8',  // Another one may be better.
  hr: 'CP1250',
  hu: 'CP1250',
  id: 'CP1252',
  it: 'CP1252',
  ja: 'CP932',  // Alternatively SHIFT-JIS.
  ko: 'CP949',  // Alternatively EUC-KR.
  lt: 'CP1257',
  lv: 'CP1257',
  ms: 'CP1252',
  nl: 'CP1252',
  no: 'CP1252',
  pl: 'CP1250',
  pt_BR: 'CP1252',
  pt_PT: 'CP1252',
  ro: 'CP1250',
  ru: 'CP1251',
  sk: 'CP1250',
  sl: 'CP1250',
  sr: 'CP1251',
  sv: 'CP1252',
  th: 'CP874',  // Confirm!
  tr: 'CP1254',
  uk: 'CP1251',
  vi: 'CP1258',
  zh_CN: 'CP936',
  zh_TW: 'CP950'
};

/**
 * @return {boolean} True if volume is ready to be used.
 */
unpacker.Volume.prototype.isReady = function() {
  return !!this.metadata;
};

/**
 * @return {boolean} True if volume is in use.
 */
unpacker.Volume.prototype.inUse = function() {
  return this.decompressor.hasRequestsInProgress() ||
         Object.keys(this.openedFiles).length > 0;
};

/**
 * Initializes the volume by reading its metadata.
 * @param {function()} onSuccess Callback to execute on success.
 * @param {function(!ProviderError)} onError Callback to execute on error.
 */
unpacker.Volume.prototype.initialize = function(onSuccess, onError) {
  var requestId = unpacker.Volume.DEFAULT_READ_METADATA_REQUEST_ID;
  this.decompressor.readMetadata(requestId, this.encoding, function(metadata) {
    // Make a deep copy of metadata.
    this.metadata = /** @type {!Object<string, !EntryMetadata>} */ (JSON.parse(
            JSON.stringify(metadata)));
    correctMetadata(this.metadata);

    onSuccess();
  }.bind(this), onError);
};

/**
 * Obtains the metadata for a single entry in the archive. Assumes metadata is
 * loaded.
 * @param {!unpacker.types.GetMetadataRequestedOptions} options Options for
 *     getting the metadata of an entry.
 * @param {function(!EntryMetadata)} onSuccess Callback to execute on success.
 * @param {function(!ProviderError)} onError Callback to execute on error.
 */
unpacker.Volume.prototype.onGetMetadataRequested = function(options, onSuccess,
                                                            onError) {
  console.assert(this.isReady(), 'Metadata must be loaded.');
  var entryMetadata = this.getEntryMetadata_(options.entryPath);
  if (!entryMetadata)
    onError('NOT_FOUND');
  else
    onSuccess(entryMetadata);
};

/**
 * Reads a directory contents from metadata. Assumes metadata is loaded.
 * @param {!unpacker.types.ReadDirectoryRequestedOptions} options Options
 *     for reading the contents of a directory.
 * @param {function(!Array<!EntryMetadata>, boolean)} onSuccess Callback to
 *     execute on success.
 * @param {function(!ProviderError)} onError Callback to execute on error.
 */
unpacker.Volume.prototype.onReadDirectoryRequested = function(
    options, onSuccess, onError) {
  console.assert(this.isReady(), 'Metadata must be loaded.');
  var directoryMetadata = this.getEntryMetadata_(options.directoryPath);
  if (!directoryMetadata) {
    onError('NOT_FOUND');
    return;
  }
  if (!directoryMetadata.isDirectory) {
    onError('NOT_A_DIRECTORY');
    return;
  }

  // Convert dictionary entries to an array.
  var entries = [];
  for (var entry in directoryMetadata.entries) {
    entries.push(directoryMetadata.entries[entry]);
  }

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

/**
 * Opens a file for read or write.
 * @param {!unpacker.types.OpenFileRequestedOptions} options Options for
 *     opening a file.
 * @param {function()} onSuccess Callback to execute on success.
 * @param {function(!ProviderError)} onError Callback to execute on error.
 */
unpacker.Volume.prototype.onOpenFileRequested = function(options, onSuccess,
                                                         onError) {
  console.assert(this.isReady(), 'Metadata must be loaded.');
  if (options.mode != 'READ') {
    onError('INVALID_OPERATION');
    return;
  }

  var metadata = this.getEntryMetadata_(options.filePath);
  if (!metadata) {
    onError('NOT_FOUND');
    return;
  }

  this.openedFiles[options.requestId] = options;

  this.decompressor.openFile(
      options.requestId, metadata.index, this.encoding, function() {
        onSuccess();
      }.bind(this), function(error) {
        delete this.openedFiles[options.requestId];
        onError('FAILED');
      }.bind(this));
};

/**
 * Closes a file identified by options.openRequestId.
 * @param {!unpacker.types.CloseFileRequestedOptions} options Options for
 *     closing a file.
 * @param {function()} onSuccess Callback to execute on success.
 * @param {function(!ProviderError)} onError Callback to execute on error.
 */
unpacker.Volume.prototype.onCloseFileRequested = function(options, onSuccess,
                                                          onError) {
  console.assert(this.isReady(), 'Metadata must be loaded.');
  var openRequestId = options.openRequestId;
  var openOptions = this.openedFiles[openRequestId];
  if (!openOptions) {
    onError('INVALID_OPERATION');
    return;
  }

  this.decompressor.closeFile(options.requestId, openRequestId, function() {
    delete this.openedFiles[openRequestId];
    onSuccess();
  }.bind(this), onError);
};

/**
 * Reads the contents of a file identified by options.openRequestId.
 * @param {!unpacker.types.ReadFileRequestedOptions} options Options for
 *     reading a file's contents.
 * @param {function(!ArrayBuffer, boolean)} onSuccess Callback to execute on
 *     success.
 * @param {function(!ProviderError)} onError Callback to execute on error.
 */
unpacker.Volume.prototype.onReadFileRequested = function(options, onSuccess,
                                                         onError) {
  console.assert(this.isReady(), 'Metadata must be loaded.');
  var openOptions = this.openedFiles[options.openRequestId];
  if (!openOptions) {
    onError('INVALID_OPERATION');
    return;
  }

  var offset = options.offset;
  var length = options.length;
  // Offset and length should be validated by the API.
  console.assert(offset >= 0, 'Offset should be >= 0.');
  console.assert(length >= 0, 'Length should be >= 0.');

  var fileSize = this.getEntryMetadata_(openOptions.filePath).size;
  if (offset >= fileSize || length == 0) {  // No more data.
    onSuccess(new ArrayBuffer(0), false /* Last call. */);
    return;
  }
  length = Math.min(length, fileSize - offset);

  this.decompressor.readFile(options.requestId, options.openRequestId,
                             offset, length, onSuccess, onError);
};

/**
 * Gets the metadata for an entry based on its path.
 * @param {string} entryPath The full path to the entry.
 * @return {?Object} The correspondent metadata.
 * @private
 */
unpacker.Volume.prototype.getEntryMetadata_ = function(entryPath) {
  var pathArray = entryPath.split('/');

  // Remove empty strings resulted after split. As paths start with '/' we will
  // have an empty string at the beginning of pathArray and possible an
  // empty string at the end for directories (e.g. /path/to/dir/). The code
  // assumes entryPath cannot have consecutive '/'.
  pathArray.splice(0, 1);

  if (pathArray.length > 0) {  // In case of 0 this is root directory.
    var lastIndex = pathArray.length - 1;
    if (pathArray[lastIndex] == '')
      pathArray.splice(lastIndex);
  }

  // Get the actual metadata by iterating through every directory metadata
  // on the path to the entry.
  var entryMetadata = this.metadata;
  for (var i = 0, limit = pathArray.length; i < limit; i++) {
    if (!entryMetadata ||
        !entryMetadata.isDirectory && i != limit - 1 /* Parent directory. */)
      return null;
    entryMetadata = entryMetadata.entries[pathArray[i]];
  }

  return entryMetadata;
};
