"use strict";
var utils = require('./utils');

var LinkedList = module.exports = {
    // basic validity tests on a circular linked list a
    valid: function(a) {
        utils.assert(a, "list falsy");
        utils.assert(a._previousSibling, "previous falsy");
        utils.assert(a._nextSibling, "next falsy");
        // xxx check that list is actually circular
        return true;
    },
    // insert a before b
    insertBefore: function(a, b) {
        utils.assert(LinkedList.valid(a) && LinkedList.valid(b));
        var a_first = a, a_last = a._previousSibling;
        var b_first = b, b_last = b._previousSibling;
        a_first._previousSibling = b_last;
        a_last._nextSibling = b_first;
        b_last._nextSibling = a_first;
        b_first._previousSibling = a_last;
        utils.assert(LinkedList.valid(a) && LinkedList.valid(b));
    },
    // replace a single node a with a list b (which could be null)
    replace: function(a, b) {
        utils.assert(LinkedList.valid(a) && (b===null || LinkedList.valid(b)));
        if (b!==null) {
            LinkedList.insertBefore(b, a);
        }
        LinkedList.remove(a);
        utils.assert(LinkedList.valid(a) && (b===null || LinkedList.valid(b)));
    },
    // remove single node a from its list
    remove: function(a) {
        utils.assert(LinkedList.valid(a));
        var prev = a._previousSibling;
        if (prev === a) { return; }
        var next = a._nextSibling;
        prev._nextSibling = next;
        next._previousSibling = prev;
        a._previousSibling = a._nextSibling = a;
        utils.assert(LinkedList.valid(a));
    }
};
