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

/**
 * VolumeManager is responsible for tracking list of mounted volumes.
 *
 * @constructor
 * @implements {VolumeManager}
 * @extends {cr.EventTarget}
 */
function VolumeManagerImpl() {
  /** @override */
  this.volumeInfoList = new VolumeInfoListImpl();

  /**
   * The list of archives requested to mount. We will show contents once
   * archive is mounted, but only for mounts from within this filebrowser tab.
   * @type {Object<Object>}
   * @private
   */
  this.requests_ = {};

  /**
   * Queue for mounting.
   * @type {AsyncUtil.Queue}
   * @private
   */
  this.mountQueue_ = new AsyncUtil.Queue();

  // The status should be merged into VolumeManager.
  // TODO(hidehiko): Remove them after the migration.
  /**
   * Connection state of the Drive.
   * @type {VolumeManagerCommon.DriveConnectionState}
   * @private
   */
  this.driveConnectionState_ = {
    type: VolumeManagerCommon.DriveConnectionType.OFFLINE,
    reason: VolumeManagerCommon.DriveConnectionReason.NO_SERVICE,
    hasCellularNetworkAccess: false
  };

  chrome.fileManagerPrivate.onDriveConnectionStatusChanged.addListener(
      this.onDriveConnectionStatusChanged_.bind(this));
  this.onDriveConnectionStatusChanged_();
}

/**
 * Invoked when the drive connection status is changed.
 * @private
 */
VolumeManagerImpl.prototype.onDriveConnectionStatusChanged_ = function() {
  chrome.fileManagerPrivate.getDriveConnectionState(function(state) {
    this.driveConnectionState_ = state;
    cr.dispatchSimpleEvent(this, 'drive-connection-changed');
  }.bind(this));
};

/** @override */
VolumeManagerImpl.prototype.getDriveConnectionState = function() {
  return this.driveConnectionState_;
};

/**
 * VolumeManager extends cr.EventTarget.
 */
VolumeManagerImpl.prototype.__proto__ = cr.EventTarget.prototype;

/**
 * Adds new volume info from the given volumeMetadata. If the corresponding
 * volume info has already been added, the volumeMetadata is ignored.
 * @param {!chrome.fileManagerPrivate.VolumeMetadata} volumeMetadata
 * @return {!Promise<!VolumeInfo>}
 * @private
 */
VolumeManagerImpl.prototype.addVolumeMetadata_ = function(volumeMetadata) {
  return volumeManagerUtil.createVolumeInfo(volumeMetadata).then(
      (/**
       * @param {!VolumeInfo} volumeInfo
       * @return {!VolumeInfo}
       */
      function(volumeInfo) {
        // We don't show Downloads and Drive on volume list if they have mount
        // error, since users can do nothing in this situation.
        // We show Removable and Provided volumes regardless of mount error so
        // that users can unmount or format the volume.
        // TODO(fukino): Once the Files app gets ready, show erroneous Drive
        // volume so that users can see auth warning banner on the volume.
        // crbug.com/517772.
        var shouldShow = true;
        switch (volumeInfo.volumeType) {
          case VolumeManagerCommon.VolumeType.DOWNLOADS:
          case VolumeManagerCommon.VolumeType.DRIVE:
            shouldShow = !!volumeInfo.fileSystem;
            break;
        }
        if (!shouldShow)
            return volumeInfo;
        if (this.volumeInfoList.findIndex(volumeInfo.volumeId) === -1) {
          this.volumeInfoList.add(volumeInfo);

          // Update the network connection status, because until the drive is
          // initialized, the status is set to not ready.
          // TODO(mtomasz): The connection status should be migrated into
          // chrome.fileManagerPrivate.VolumeMetadata.
          if (volumeMetadata.volumeType ===
              VolumeManagerCommon.VolumeType.DRIVE) {
            this.onDriveConnectionStatusChanged_();
          }
        } else if (volumeMetadata.volumeType ===
            VolumeManagerCommon.VolumeType.REMOVABLE) {
          // Update for remounted USB external storage, because they were
          // remounted to switch read-only policy.
          this.volumeInfoList.add(volumeInfo);
        }
        return volumeInfo;
      }).bind(this));
};

/**
 * Initializes mount points.
 * @param {function()} callback Called upon the completion of the
 *     initialization.
 * @private
 */
VolumeManagerImpl.prototype.initialize_ = function(callback) {
  chrome.fileManagerPrivate.onMountCompleted.addListener(
      this.onMountCompleted_.bind(this));
  console.debug('Requesting volume list.');
  chrome.fileManagerPrivate.getVolumeMetadataList(function(volumeMetadataList) {
    console.debug(
        'Volume list fetched with: ' + volumeMetadataList.length + ' items.');
    // We must subscribe to the mount completed event in the callback of
    // getVolumeMetadataList. crbug.com/330061.
    // But volumes reported by onMountCompleted events must be added after the
    // volumes in the volumeMetadataList are mounted. crbug.com/135477.
    this.mountQueue_.run(function(inCallback) {
      // Create VolumeInfo for each volume.
      Promise.all(
          volumeMetadataList.map(function(volumeMetadata) {
            console.debug(
                'Initializing volume: ' + volumeMetadata.volumeId);
            return this.addVolumeMetadata_(volumeMetadata).then(
                function(volumeInfo) {
                  console.debug('Initialized volume: ' + volumeInfo.volumeId);
                });
          }.bind(this)))
          .then(function() {
            console.debug('Initialized all volumes.');
            // Call the callback of the initialize function.
            callback();
            // Call the callback of AsyncQueue. Maybe it invokes callbacks
            // registered by mountCompleted events.
            inCallback();
          });
    }.bind(this));
  }.bind(this));
};

/**
 * Event handler called when some volume was mounted or unmounted.
 * @param {chrome.fileManagerPrivate.MountCompletedEvent} event Received event.
 * @private
 */
VolumeManagerImpl.prototype.onMountCompleted_ = function(event) {
  this.mountQueue_.run(function(callback) {
    switch (event.eventType) {
      case 'mount':
        var requestKey = this.makeRequestKey_(
            'mount',
            event.volumeMetadata.sourcePath || '');

        if (event.status === 'success' ||
            event.status ===
                VolumeManagerCommon.VolumeError.UNKNOWN_FILESYSTEM ||
            event.status ===
                VolumeManagerCommon.VolumeError.UNSUPPORTED_FILESYSTEM) {
          this.addVolumeMetadata_(event.volumeMetadata).then(
              function(volumeInfo) {
                this.finishRequest_(requestKey, event.status, volumeInfo);
                callback();
              }.bind(this));
        } else if (event.status ===
            VolumeManagerCommon.VolumeError.ALREADY_MOUNTED) {
          var navigationEvent =
              new Event(VolumeManagerCommon.VOLUME_ALREADY_MOUNTED);
          navigationEvent.volumeId = event.volumeMetadata.volumeId;
          this.dispatchEvent(navigationEvent);
          this.finishRequest_(requestKey, event.status, volumeInfo);
          callback();
        } else {
          console.warn('Failed to mount a volume: ' + event.status);
          this.finishRequest_(requestKey, event.status);
          callback();
        }
        break;

      case 'unmount':
        var volumeId = event.volumeMetadata.volumeId;
        var status = event.status;
        var requestKey = this.makeRequestKey_('unmount', volumeId);
        var requested = requestKey in this.requests_;
        var volumeInfoIndex =
            this.volumeInfoList.findIndex(volumeId);
        var volumeInfo = volumeInfoIndex !== -1 ?
            this.volumeInfoList.item(volumeInfoIndex) : null;
        if (event.status === 'success' && !requested && volumeInfo) {
          console.warn('Unmounted volume without a request: ' + volumeId);
          var e = new Event('externally-unmounted');
          e.volumeInfo = volumeInfo;
          this.dispatchEvent(e);
        }

        this.finishRequest_(requestKey, status);
        if (event.status === 'success')
          this.volumeInfoList.remove(event.volumeMetadata.volumeId);
        console.debug('unmounted volume: ' + volumeId);
        callback();
        break;
    }
  }.bind(this));
};

/**
 * Creates string to match mount events with requests.
 * @param {string} requestType 'mount' | 'unmount'. TODO(hidehiko): Replace by
 *     enum.
 * @param {string} argument Argument describing the request, eg. source file
 *     path of the archive to be mounted, or a volumeId for unmounting.
 * @return {string} Key for |this.requests_|.
 * @private
 */
VolumeManagerImpl.prototype.makeRequestKey_ = function(requestType, argument) {
  return requestType + ':' + argument;
};

/** @override */
VolumeManagerImpl.prototype.mountArchive = function(
    fileUrl, successCallback, errorCallback) {
  chrome.fileManagerPrivate.addMount(fileUrl, function(sourcePath) {
    console.info(
        'Mount request: url=' + fileUrl + '; sourcePath=' + sourcePath);
    var requestKey = this.makeRequestKey_('mount', sourcePath);
    this.startRequest_(requestKey, successCallback, errorCallback);
  }.bind(this));
};

/** @override */
VolumeManagerImpl.prototype.unmount = function(volumeInfo,
                                           successCallback,
                                           errorCallback) {
  chrome.fileManagerPrivate.removeMount(volumeInfo.volumeId);
  var requestKey = this.makeRequestKey_('unmount', volumeInfo.volumeId);
  this.startRequest_(requestKey, successCallback, errorCallback);
};

/** @override */
VolumeManagerImpl.prototype.configure = function(volumeInfo) {
  return new Promise(function(fulfill, reject) {
    chrome.fileManagerPrivate.configureVolume(
        volumeInfo.volumeId,
        function() {
          if (chrome.runtime.lastError)
            reject(chrome.runtime.lastError.message);
          else
            fulfill();
        });
  });
};

/** @override */
VolumeManagerImpl.prototype.getVolumeInfo = function(entry) {
  for (let i = 0; i < this.volumeInfoList.length; i++) {
    const volumeInfo = this.volumeInfoList.item(i);
    if (volumeInfo.fileSystem &&
        util.isSameFileSystem(volumeInfo.fileSystem, entry.filesystem)) {
      return volumeInfo;
    }
    // Additionally, check fake entries.
    for (let key in volumeInfo.fakeEntries_) {
      const fakeEntry = volumeInfo.fakeEntries_[key];
      if (util.isSameEntry(fakeEntry, entry))
        return volumeInfo;
    }
  }
  return null;
};

/** @override */
VolumeManagerImpl.prototype.getCurrentProfileVolumeInfo = function(volumeType) {
  for (var i = 0; i < this.volumeInfoList.length; i++) {
    var volumeInfo = this.volumeInfoList.item(i);
    if (volumeInfo.profile.isCurrentProfile &&
        volumeInfo.volumeType === volumeType)
      return volumeInfo;
  }
  return null;
};

/** @override */
VolumeManagerImpl.prototype.getLocationInfo = function(entry) {
  var volumeInfo = this.getVolumeInfo(entry);

  if (util.isFakeEntry(entry)) {
    return new EntryLocationImpl(
        volumeInfo, assert(entry.rootType),
        true /* the entry points a root directory. */,
        true /* fake entries are read only. */);
  }

  if (!volumeInfo)
    return null;

  var rootType;
  var isReadOnly;
  var isRootEntry;
  if (volumeInfo.volumeType === VolumeManagerCommon.VolumeType.DRIVE) {
    // For Drive, the roots are /root, /team_drives, /Computers and /other,
    // instead of /. Root URLs contain trailing slashes.
    if (entry.fullPath == '/root' || entry.fullPath.indexOf('/root/') === 0) {
      rootType = VolumeManagerCommon.RootType.DRIVE;
      isReadOnly = volumeInfo.isReadOnly;
      isRootEntry = entry.fullPath === '/root';
    } else if (
        entry.fullPath == VolumeManagerCommon.TEAM_DRIVES_DIRECTORY_PATH ||
        entry.fullPath.indexOf(
            VolumeManagerCommon.TEAM_DRIVES_DIRECTORY_PATH + '/') === 0) {
      if (entry.fullPath == VolumeManagerCommon.TEAM_DRIVES_DIRECTORY_PATH) {
        rootType = VolumeManagerCommon.RootType.TEAM_DRIVES_GRAND_ROOT;
        isReadOnly = true;
        isRootEntry = true;
      } else {
        rootType = VolumeManagerCommon.RootType.TEAM_DRIVE;
        if (util.isTeamDriveRoot(entry)) {
          isReadOnly = false;
          isRootEntry = true;
        } else {
          // Regular files/directories under Team Drives.
          isRootEntry = false;
          isReadOnly = volumeInfo.isReadOnly;
        }
      }
    } else if (
        entry.fullPath == VolumeManagerCommon.COMPUTERS_DIRECTORY_PATH ||
        entry.fullPath.indexOf(
            VolumeManagerCommon.COMPUTERS_DIRECTORY_PATH + '/') === 0) {
      if (entry.fullPath == VolumeManagerCommon.COMPUTERS_DIRECTORY_PATH) {
        rootType = VolumeManagerCommon.RootType.COMPUTERS_GRAND_ROOT;
        isReadOnly = true;
        isRootEntry = true;
      } else {
        rootType = VolumeManagerCommon.RootType.COMPUTER;
        if (util.isComputersRoot(entry)) {
          isReadOnly = false;
          isRootEntry = true;
        } else {
          // Regular files/directories under a Computer entry.
          isRootEntry = false;
          isReadOnly = volumeInfo.isReadOnly;
        }
      }
    } else if (entry.fullPath == '/other' ||
               entry.fullPath.indexOf('/other/') === 0) {
      rootType = VolumeManagerCommon.RootType.DRIVE_OTHER;
      isReadOnly = true;
      isRootEntry = entry.fullPath === '/other';
    } else if (
        entry.fullPath === '/.files-by-id' ||
        entry.fullPath.indexOf('/.files-by-id/') === 0) {
      rootType = VolumeManagerCommon.RootType.DRIVE_OTHER;

      // /.files-by-id/<id> is read-only, but /.files-by-id/<id>/foo is
      // read-write.
      isReadOnly = entry.fullPath.split('/').length < 4;
      isRootEntry = entry.fullPath === '/.files-by-id';
    } else {
      // Accessing Drive files outside of /drive/root and /drive/other is not
      // allowed, but can happen. Therefore returning null.
      return null;
    }
  } else {
    rootType =
        VolumeManagerCommon.getRootTypeFromVolumeType(volumeInfo.volumeType);
    isRootEntry = util.isSameEntry(entry, volumeInfo.fileSystem.root);
    // Although "Play files" root directory is writable in file system level,
    // we prohibit write operations on it in the UI level to avoid confusion.
    // Users can still have write access in sub directories like
    // /Play files/Pictures, /Play files/DCIM, etc...
    if (volumeInfo.volumeType == VolumeManagerCommon.VolumeType.ANDROID_FILES &&
        isRootEntry) {
      isReadOnly = true;
    } else {
      isReadOnly = volumeInfo.isReadOnly;
    }
  }

  return new EntryLocationImpl(volumeInfo, rootType, isRootEntry, isReadOnly);
};

/** @override */
VolumeManagerImpl.prototype.findByDevicePath = function(devicePath) {
  for (let i = 0; i < this.volumeInfoList.length; i++) {
    const volumeInfo = this.volumeInfoList.item(i);
    if (volumeInfo.devicePath && volumeInfo.devicePath === devicePath)
      return volumeInfo;
  }
  return null;
};

/** @override */
VolumeManagerImpl.prototype.whenVolumeInfoReady = function(volumeId) {
  return new Promise((fulfill) => {
    const handler = () => {
      const index = this.volumeInfoList.findIndex(volumeId);
      if (index !== -1) {
        fulfill(this.volumeInfoList.item(index));
        this.volumeInfoList.removeEventListener('splice', handler);
      }
    };
    this.volumeInfoList.addEventListener('splice', handler);
    handler();
  });
};

/**
 * @param {string} key Key produced by |makeRequestKey_|.
 * @param {function(VolumeInfo)} successCallback To be called when the request
 *     finishes successfully.
 * @param {function(VolumeManagerCommon.VolumeError)} errorCallback To be called
 *     when the request fails.
 * @private
 */
VolumeManagerImpl.prototype.startRequest_ = function(key,
    successCallback, errorCallback) {
  if (key in this.requests_) {
    var request = this.requests_[key];
    request.successCallbacks.push(successCallback);
    request.errorCallbacks.push(errorCallback);
  } else {
    this.requests_[key] = {
      successCallbacks: [successCallback],
      errorCallbacks: [errorCallback],

      timeout: setTimeout(this.onTimeout_.bind(this, key),
                          volumeManagerUtil.TIMEOUT)
    };
  }
};

/**
 * Called if no response received in |TIMEOUT|.
 * @param {string} key Key produced by |makeRequestKey_|.
 * @private
 */
VolumeManagerImpl.prototype.onTimeout_ = function(key) {
  this.invokeRequestCallbacks_(this.requests_[key],
                               VolumeManagerCommon.VolumeError.TIMEOUT);
  delete this.requests_[key];
};

/**
 * @param {string} key Key produced by |makeRequestKey_|.
 * @param {VolumeManagerCommon.VolumeError|string} status Status received
 *     from the API.
 * @param {VolumeInfo=} opt_volumeInfo Volume info of the mounted volume.
 * @private
 */
VolumeManagerImpl.prototype.finishRequest_ =
    function(key, status, opt_volumeInfo) {
  var request = this.requests_[key];
  if (!request)
    return;

  clearTimeout(request.timeout);
  this.invokeRequestCallbacks_(request, status, opt_volumeInfo);
  delete this.requests_[key];
};

/**
 * @param {Object} request Structure created in |startRequest_|.
 * @param {VolumeManagerCommon.VolumeError|string} status If status ===
 *     'success' success callbacks are called.
 * @param {VolumeInfo=} opt_volumeInfo Volume info of the mounted volume.
 * @private
 */
VolumeManagerImpl.prototype.invokeRequestCallbacks_ = function(
    request, status, opt_volumeInfo) {
  var callEach = function(callbacks, self, args) {
    for (var i = 0; i < callbacks.length; i++) {
      callbacks[i].apply(self, args);
    }
  };
  if (status === 'success') {
    callEach(request.successCallbacks, this, [opt_volumeInfo]);
  } else {
    volumeManagerUtil.validateError(status);
    callEach(request.errorCallbacks, this, [status]);
  }
};
