/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
*/

// contains PLIST utility functions
var __ = require('underscore');
var plist = require('plist');

// adds node to doc at selector
module.exports.graftPLIST = graftPLIST;
function graftPLIST (doc, xml, selector) {
    var obj = plist.parse('<plist>' + xml + '</plist>');

    var node = doc[selector];
    if (node && Array.isArray(node) && Array.isArray(obj)) {
        node = node.concat(obj);
        for (var i = 0; i < node.length; i++) {
            for (var j = i + 1; j < node.length; ++j) {
                if (nodeEqual(node[i], node[j])) { node.splice(j--, 1); }
            }
        }
        doc[selector] = node;
    } else {
        // plist uses objects for <dict>. If we have two dicts we merge them instead of
        // overriding the old one. See CB-6472
        if (node && __.isObject(node) && __.isObject(obj) && !__.isDate(node) && !__.isDate(obj)) { // arrays checked above
            __.extend(obj, node);
        }
        doc[selector] = obj;
    }

    return true;
}

// removes node from doc at selector
module.exports.prunePLIST = prunePLIST;
function prunePLIST (doc, xml, selector) {
    var obj = plist.parse('<plist>' + xml + '</plist>');

    pruneOBJECT(doc, selector, obj);

    return true;
}

function pruneOBJECT (doc, selector, fragment) {
    if (Array.isArray(fragment) && Array.isArray(doc[selector])) {
        var empty = true;
        for (var i in fragment) {
            for (var j in doc[selector]) {
                empty = pruneOBJECT(doc[selector], j, fragment[i]) && empty;
            }
        }
        if (empty) {
            delete doc[selector];
            return true;
        }
    } else if (nodeEqual(doc[selector], fragment)) {
        delete doc[selector];
        return true;
    }

    return false;
}

function nodeEqual (node1, node2) {
    if (typeof node1 !== typeof node2) { return false; } else if (typeof node1 === 'string') {
        node2 = escapeRE(node2).replace(/\\\$\(\S+\)/gm, '(.*?)');
        return new RegExp('^' + node2 + '$').test(node1);
    } else {
        for (var key in node2) {
            if (!nodeEqual(node1[key], node2[key])) return false;
        }
        return true;
    }
}

// escape string for use in regex
function escapeRE (str) {
    return str.replace(/[-[\]/{}()*+?.\\^$|]/g, '\\$&');
}
