// answer questions about Fastly status
// NOT YET IMPLEMENTED

var
    _       = require('lodash'),
    P       = require('bluebird'),
    restify = require('restify')
    ;

var Fastly = module.exports = function Fastly(opts)
{
    this.apikey = opts.apikey;
    this.client = restify.createJSONClient(
    {
        url: 'https://api.fastly.com',
        headers: { 'x-fastly-key': opts.apikey }
    });
};

Fastly.prototype.name = 'fastly';
Fastly.prototype.pattern = /^fastly\s+(.+)\s?(\w+)?$/;

Fastly.prototype.matches = function matches(msg)
{
    return /^fastly/.test(msg);
};

Fastly.prototype.respond = function respond(message)
{
    var msg = message.text;
    var matches = this.pattern.exec(msg);
    if (!matches) return message.done(this.help());

    var service = matches[1];
    var field = matches[2];

    // I don't like this.
    var promise;
    if (service === 'services' && !field)
    {
        promise = this.listServices();
    }
    else
    {
        promise = this.fetchField(service, field);
    }

    promise.then(function(reply)
    {
        message.done(reply);
    }).done();
};

Fastly.prototype.help = function help(msg)
{
    return 'get current stats from fastly\n' +
        'fastly services: list all known services\n' +
        'fastly <service> <field> (eg, status_503, errors, hits)';
};

Fastly.prototype.listServices = function listServices()
{
    return this.fetchServices()
    .then(function(services)
    {
        return 'Fastly services:\n' + _.map(services, function(v, k) { return k; }).join('\n');
    }, function(err) { return err.message; });
};

Fastly.prototype.fetchField = function fetchField(service, field)
{
    var self = this,
        id;

    return this.fetchServices()
    .then(function(services)
    {
        id = services[service];
        if (!id)
            throw new Error('Cannot find service ' + service);

        return self.execute('/stats/service/' + id + '?by=minute');
    })
    .then(function(response)
    {
        var fields = 0;
        var requests = 0;

        if (!response.data) return 'No data for ' + service + ' in the last 30 minutes.';

        _.each(response.data, function(item, k)
        {
            fields += parseInt(item[field], 10);
            requests += item.requests;
        });

        var last = response.data[response.data.length - 1];

        var reply = field + ' for ' + service + ':\n';
        reply += 'Last minute: ' + last[field] + ' ' + field + ' for ' + last.requests + ' requests\n';
        reply += 'Last 30 min: ' + fields + ' / ' + requests;

        return reply;
    }, function(err) { return err.message; });
};

Fastly.prototype.fetchServices = function fetchServices()
{
    return this.execute('/service')
    .then(function(reply)
    {
        var result = {};
        _.each(reply, function(service)
        {
            result[service.name] = service.id;
        });
        return result;
    });
};

Fastly.prototype.execute = function execute(uri)
{
    var deferred = P.defer(),
        self = this;

    this.client.get(uri, function(err, req, response, body)
    {
        if (err) return deferred.reject(err);
        if (!response || (response.statusCode < 200) || (response.statusCode > 302))
        {
            return deferred.reject(new Error('Fastly status code ' + response.statusCode));
        }

        deferred.resolve(body);
    });

    return deferred.promise;
}

@@ -470,25 +470,15 @@
  = /
-%5Efastly%5Cs+
 (.+)%5Cs
-?
++
 (%5Cw+
@@ -654,16 +654,121 @@
 e.text;%0A
+    msg = msg.replace(/%5Efastly%5Cs?/, '');%0A    if (msg === 'services') return this.listServices(message);%0A%0A
     var 
@@ -920,173 +920,8 @@
 %0A   
- // I don't like this.%0A    var promise;%0A    if (service === 'services' && !field)%0A    %7B%0A        promise = this.listServices();%0A    %7D%0A    else%0A    %7B%0A        promise =
  thi
@@ -952,28 +952,13 @@
 eld)
-;
 %0A    
-%7D%0A%0A    promise
 .the
@@ -1297,38 +1297,38 @@
 istServices(
+message
 )%0A%7B%0A   
- return
  this.fetchS
@@ -1380,23 +1380,29 @@
         
-return 
+message.done(
 'Fastly 
@@ -1472,16 +1472,17 @@
 in('%5Cn')
+)
 ;%0A    %7D,
@@ -1490,39 +1490,45 @@
 function(err) %7B 
-return 
+message.done(
 err.message; %7D);
@@ -1514,36 +1514,49 @@
 done(err.message
+)
 ; %7D)
+%0A    .done()
 ;%0A%7D;%0A%0AFastly.pro

Repair matching for fastly commands (service names have spaces and this is annoying).