text: /*
   * files.js: Instance methods for working with files from AWS S3
   *
   * (C) 2012 Charlie Robbins, Ken Perkins, Ross Kukulinski & the Contributors.
   *
   */
  
  var base = require('../../../core/storage'),
      pkgcloud = require('../../../../../lib/pkgcloud'),
      through = require('through2'),
      storage = pkgcloud.providers.ibm.storage,
      _ = require('lodash');
  
  //
  // ### function removeFile (container, file, callback)
  // #### @container {string} Name of the container to destroy the file in
  // #### @file {string} Name of the file to destroy.
  // #### @callback {function} Continuation to respond to when complete.
  // Destroys the `file` in the specified `container`.
  //
  exports.removeFile = function (container, file, callback) {
    var self = this;
  
    if (container instanceof storage.Container) {
      container = container.name;
    }
  
    if (file instanceof storage.File) {
      file = file.name;
    }
  
    self.s3.deleteObject({
      Bucket: container,
      Key: file
    }, function(err, data) {
      return err
        ? callback(err)
        : callback(null, !!data.DeleteMarker);
    });
  };
  
  exports.upload = function (options) {
    var self = this;
  
    // check for deprecated calling with a callback
    if (typeof arguments[arguments.length - 1] === 'function') {
      self.emit('log::warn', 'storage.upload no longer supports calling with a callback');
    }
  
    var s3Options = {
      Bucket: options.container instanceof base.Container ? options.container.name : options.container,
      Key: options.remote instanceof base.File ? options.remote.name : options.remote
    };
  
    if (options.cacheControl) {
      s3Options.CacheControl = options.cacheControl;
    }
  
    if (options.contentType) {
      s3Options.ContentType = options.contentType;
    }
  
    // use ACL until a more obvious permission generalization is available
    if (options.acl) {
      s3Options.ACL = options.acl;
    }
  
    // add AWS specific options
    if (options.cacheControl) {
      s3Options.CacheControl = options.cacheControl;
    }
  
    if (options.ServerSideEncryption) {
      s3Options.ServerSideEncryption = options.ServerSideEncryption;
    }
  
    var proxyStream = through(),
      writableStream = self.s3Stream.upload(s3Options);
  
    // we need a proxy stream so we can always return a file model
    // via the 'success' event
    writableStream.on('uploaded', function(details) {
      proxyStream.emit('success', new storage.File(self, details));
    });
  
    writableStream.on('error', function(err) {
      proxyStream.emit('error', err);
    });
  
    writableStream.on('data', function (chunk) {
      proxyStream.emit('data', chunk);
    });
  
    proxyStream.pipe(writableStream);
  
    return proxyStream;
  };
  
  exports.download = function (options) {
    var self = this;
  
    return self.s3.getObject({
      Bucket: options.container instanceof base.Container ? options.container.name : options.container,
      Key: options.remote instanceof base.File ? options.remote.name : options.remote
    }).createReadStream();
  
  };
  
  exports.getFile = function (container, file, callback) {
    var containerName = container instanceof base.Container ? container.name : container,
        self = this;
  
    self.s3.headObject({
      Bucket: containerName,
      Key: file
    }, function(err, data) {
      return err
        ? callback(err)
        : callback(null, new storage.File(self, _.extend(data, {
        container: container,
        name: file
      })));
    });
  };
  
  exports.getFiles = function (container, options, callback) {
    var containerName = container instanceof base.Container ? container.name : container,
        self = this;
  
    if (typeof options === 'function') {
      callback = options;
      options = {};
    }
    else if (!options) {
      options = {};
    }
  
    var s3Options = {
      Bucket: containerName
    };
  
    if (options.marker) {
      s3Options.Marker = options.marker;
    }
  
    if (options.prefix) {
      s3Options.Prefix = options.prefix;
    }
  
    if (options.maxKeys) {
      s3Options.MaxKeys = options.maxKeys;
    }
  
    self.s3.listObjects(s3Options, function(err, data) {
      return err
        ? callback(err)
        : callback(null, self._toArray(data.Contents).map(function (file) {
        file.container = container;
        return new storage.File(self, file);
      }), {
        isTruncated: data.IsTruncated,
        marker: data.Marker,
        nextMarker: data.NextMarker
      });
    });
  };
  
  