var path = require('path');
var mime = require('mime-types');

var model = require('./model');
var ReleaseAsset = require('./release-asset');

var Release = model.create(function(repo, releaseId) {
    this.repo = repo;
    this.id = releaseId;
    this._infos;
});

// Relations
Release.prototype.asset = model.getter(ReleaseAsset);

// Return list of assets
Release.prototype.assets = function() {
    return this.client.get(this.url('assets'))
        .get('body');
};

// Return api url for the release
Release.prototype.url = function(part) {
    return this.repo.url('releases/'+this.id, part);
};

// Get details about the release
Release.prototype.info = function() {
    var that = this;

    return this.client.get(this.url())
        .get('body')
        .tap(function(infos) {
            that._infos = infos;
        });
};

// Edit this release
Release.prototype.edit = function(params) {
    return this.client.patch(this.url(), params)
        .get('body');
};

// Upload an asset
Release.prototype.upload = function(output, opts) {
    var that = this;

    opts = _.defaults(opts || {}, {
        name: null,
        mime: null
    });

    // Normalize to a stream
    if (_.isString(output)) {
        opts.name = opts.name || path.basename(output);
        output = fs.createReadStream(output);
    } else {
        if (!opts.name) throw "Need a 'name' when uploading a stream";
    }
    if (!opts.mime) opts.mime = mime.lookup(opts.name) || 'application/octet-stream';

    return Q()
    .then(function() {
        return that._infos || that.info();
    })
    .then(function(release) {
        var d = Q.defer();
        var uploadUrl = release.uploadUrl.replace('{?name}', '?name='+encodeURIComponent(opts.name));

        output.on('error', function(err) {
            d.reject(err);
        });

        that.client.post(uploadUrl, {}, {
            headers: {
                'Content-Type': opts.mime
            },
            process: function(r) {
                output.pipe(r);
            }
        })
        .then(function() {
            d.resolve();
        }, function(err) {
            d.reject(err);
        });

        return d.promise;
    });
};

// Remove the release
Release.prototype.destroy = function() {
    return this.client.del(this.url);
};

module.exports = Release;

@@ -1,12 +1,85 @@
+var Q = require('q');%0Avar _ = require('lodash');%0Avar fs = require('fs');%0A
 var path = r
@@ -90,24 +90,24 @@
 re('path');%0A
-
 var mime = r
@@ -1131,24 +1131,48 @@
 that = this;
+%0A    var originalOutput;
 %0A%0A    opts =
@@ -1230,16 +1230,36 @@
    mime:
+ null,%0A        size:
  null%0A  
@@ -1320,24 +1320,57 @@
 (output)) %7B%0A
+        originalOutput = output;%0A
         opts
@@ -1494,16 +1494,30 @@
 pts.name
+ %7C%7C !opts.size
 ) throw 
@@ -1526,16 +1526,33 @@
 eed 
-a 
 'name'
+ and 'size' options
  whe
@@ -1697,32 +1697,196 @@
 en(function() %7B%0A
+        if (opts.size) return opts.size;%0A%0A        return Q.nfcall(fs.stat, originalOutput).get('size');%0A    %7D)%0A    .then(function(size) %7B%0A        opts.size = size;%0A
         return t
@@ -2014,17 +2014,18 @@
 e.upload
-U
+_u
 rl.repla
@@ -2228,16 +2228,16 @@
 ders: %7B%0A
-
         
@@ -2269,16 +2269,61 @@
 pts.mime
+,%0A                'Content-Length': opts.size
 %0A       

Fix upload of assets in release