/**
    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.
*/
/* eslint no-useless-escape: 0 */

// 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, '\\$&');
}
