var xhr = require('xhr');
var serializeHTML = require('print-html');
var log = require('./log');

/* Updater class */
function Updater(url, storage, throttleDelay) {
    throttleDelay = throttleDelay || 60;

    // we don't know if authorization is needed yet, so we assume it's not needed
    // until we receive an authorization error
    var needAuthorization = false;

    // store the last update dates for each page
    var lastUpdates = {};

    function getAuthorization() {
        return storage.get('authorization');
    }

    function isAllowed(authorization) {
        return !needAuthorization || authorization;
    }

    function send(page, doc, date, analysis) {
        var pageId = page.url;
        var lastUpdate = lastUpdates[pageId] || 0;
        var elapsed = (date - lastUpdate) / 1000;
        var authorization = getAuthorization();

        if (elapsed < throttleDelay) {
            log('No update: rate limited');
            return;
        }

        if (!isAllowed(authorization)) {
            log('No update: authorization needed');
            return;
        }

        var data = {
            url: page.url,
            type: page.type,
            raw: serializeHTML(doc),
            content: analysis,
            date: date
        };

        var options = {
            url: url,
            method: 'POST',
            headers: {
                // This header is set to tell the server that we are calling it
                // from a XHR request. In that case, it must not send a
                // "WWW-Authenticate: Basic" header back to us since we can't
                // handle it properly cross-browser.
                'X-Requested-With': 'XMLHttpRequest'
            },
            json: data
        };

        if (authorization) {
            options.headers['Authorization'] = authorization;
        }

        log('Sending an update to ' + url);

        xhr(options, function (error, response) {
            var status = response.statusCode;
            var isOk = (status >= 200 && status < 300);
            var label = isOk ? 'OK' : 'FAIL';
            log(label + ' (' + status + ')');

            if (status === 401) {  // TODO: what about 403?
                needAuthorization = true;
                storage.set('authorization', undefined);
                return;
            }

            // TODO: check response status: rate-limit, etc.
            lastUpdates[pageId] = date;
        });
    }

    function render(h) {
        var authorization = getAuthorization();
        var enabledWord = isAllowed(authorization) ? 'activée' : 'désactivée';
        return h('p', 'Mise à jour ' + enabledWord);
    }

    return {
        send: send,
        render: render
    };
}

module.exports = Updater;

@@ -58,24 +58,69 @@
 int-html');%0A
+var httpHeaders = require('./http-headers');%0A
 var log = re
@@ -189,68 +189,11 @@
 rage
-, throttleDelay) %7B%0A    throttleDelay = throttleDelay %7C%7C 60;%0A
+) %7B
 %0A   
@@ -375,19 +375,19 @@
 the 
-last upda
+retry af
 te
+r
  dat
@@ -402,16 +402,21 @@
 ach page
+ type
 %0A    var
@@ -416,23 +416,27 @@
     var 
-lastUpd
+retryAfterD
 ates = %7B
@@ -687,126 +687,50 @@
 var 
-pageId = page.url;%0A        var lastUpdate = lastUpdates%5BpageId%5D %7C%7C 0;%0A        var elapsed = (date - lastUpdate) / 1000
+retryAfterDate = retryAfterDates%5Bpage.url%5D
 ;%0A  
@@ -792,31 +792,47 @@
 if (
-elapsed %3C throttleDelay
+retryAfterDate && date %3C retryAfterDate
 ) %7B%0A
@@ -2302,89 +2302,165 @@
  // 
-TODO: check response status: rate-limit, etc.%0A            lastUpdates%5BpageId%5D = d
+handle rate-limiting header%0A            var retryAfterDate = httpHeaders.getRetryAfter(response.headers);%0A            retryAfterDates%5Bpage.url%5D = retryAfterD
 ate;

Support Retry-After header for rate-liming