/*
 * Copyright 2014-present Open Networking Foundation
 *
 * Licensed 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.
 */

/*
 ONOS GUI -- Util -- General Purpose Functions
 */
(function () {
    'use strict';

    // injected services
    var $window, $log;

    // internal state
    var debugFlags = {};

    // function references
    var fcc = String.fromCharCode,
        cca = String.prototype.charCodeAt;

    function _parseDebugFlags(dbgstr) {
        var bits = dbgstr ? dbgstr.split(',') : [];
        bits.forEach(function (key) {
            debugFlags[key] = true;
        });
        $log.debug('Debug flags:', dbgstr);
    }

    function isF(f) {
        return typeof f === 'function' ? f : null;
    }

    function isA(a) {
        // NOTE: Array.isArray() is part of EMCAScript 5.1
        return Array.isArray(a) ? a : null;
    }

    function isS(s) {
        return typeof s === 'string' ? s : null;
    }

    function isO(o) {
        return (o && typeof o === 'object' && o.constructor === Object) ? o : null;
    }

    function contains(a, x) {
        return isA(a) && a.indexOf(x) > -1;
    }

    // Returns true if all names in the array are defined as functions
    // on the given api object; false otherwise.
    // Also returns false if there are properties on the api that are NOT
    //  listed in the array of names.
    function areFunctions(api, fnNames) {
        var fnLookup = {},
            extraFound = false;

        if (!isA(fnNames)) {
            return false;
        }
        var n = fnNames.length,
            i, name;
        for (i=0; i<n; i++) {
            name = fnNames[i];
            if (!isF(api[name])) {
                return false;
            }
            fnLookup[name] = true;
        }

        // check for properties on the API that are not listed in the array,
        angular.forEach(api, function (value, key) {
            if (!fnLookup[key]) {
                extraFound = true;
            }
        });
        return !extraFound;
    }

    // Returns true if all names in the array are defined as functions
    // on the given api object; false otherwise. This is a non-strict version
    // that does not care about other properties on the api.
    function areFunctionsNonStrict(api, fnNames) {
        if (!isA(fnNames)) {
            return false;
        }
        var n = fnNames.length,
            i, name;
        for (i=0; i<n; i++) {
            name = fnNames[i];
            if (!isF(api[name])) {
                return false;
            }
        }
        return true;
    }

    // Returns width and height of window inner dimensions.
    // offH, offW : offset width/height are subtracted, if present
    function windowSize(offH, offW) {
        var oh = offH || 0,
            ow = offW || 0;
        return {
            height: $window.innerHeight - oh,
            width: $window.innerWidth - ow,
        };
    }

    // Returns true if current browser determined to be a mobile device
    function isMobile() {
        var ua = $window.navigator.userAgent,
            patt = /iPhone|iPod|iPad|Silk|Android|BlackBerry|Opera Mini|IEMobile/;
        return patt.test(ua);
    }

    // Returns true if the current browser determined to be Chrome
    function isChrome() {
        var isChromium = $window.chrome,
            vendorName = $window.navigator.vendor,
            isOpera = $window.navigator.userAgent.indexOf('OPR') > -1;
        return (isChromium !== null &&
        isChromium !== undefined &&
        vendorName === 'Google Inc.' &&
        isOpera == false);
    }

    // Returns true if the current browser determined to be Safari
    function isSafari() {
        return ($window.navigator.userAgent.indexOf('Safari') !== -1 &&
        $window.navigator.userAgent.indexOf('Chrome') === -1);
    }

    // Returns true if the current browser determined to be Firefox
    function isFirefox() {
        return typeof InstallTrigger !== 'undefined';
    }

    // search through an array of objects, looking for the one with the
    // tagged property matching the given key. tag defaults to 'id'.
    // returns the index of the matching object, or -1 for no match.
    function find(key, array, tag) {
        var _tag = tag || 'id',
            idx, n, d;
        for (idx = 0, n = array.length; idx < n; idx++) {
            d = array[idx];
            if (d[_tag] === key) {
                return idx;
            }
        }
        return -1;
    }

    // search through array to find (the first occurrence of) item,
    // returning its index if found; otherwise returning -1.
    function inArray(item, array) {
        var i;
        if (isA(array)) {
            for (i=0; i<array.length; i++) {
                if (array[i] === item) {
                    return i;
                }
            }
        }
        return -1;
    }

    // remove (the first occurrence of) the specified item from the given
    // array, if any. Return true if the removal was made; false otherwise.
    function removeFromArray(item, array) {
        var found = false,
            i = inArray(item, array);
        if (i >= 0) {
            array.splice(i, 1);
            found = true;
        }
        return found;
    }

    // return true if the object is empty, return false otherwise
    function isEmptyObject(obj) {
        var key;
        for (key in obj) {
            return false;
        }
        return true;
    }

    // returns true if the two objects have all the same properties
    function sameObjProps(obj1, obj2) {
        var key;
        for (key in obj1) {
            if (obj1.hasOwnProperty(key)) {
                if (!(obj1[key] === obj2[key])) {
                    return false;
                }
            }
        }
        return true;
    }

    // returns true if the array contains the object
    // does NOT use strict object reference equality,
        // instead checks each property individually for equality
    function containsObj(arr, obj) {
        var i,
            len = arr.length;
        for (i = 0; i < len; i++) {
            if (sameObjProps(arr[i], obj)) {
                return true;
            }
        }
        return false;
    }

    // return the given string with the first character capitalized.
    function cap(s) {
        return s ? s[0].toUpperCase() + s.slice(1).toLowerCase() : s;
    }

    // return encoding structure for given parameters
    function eecode(h, w) {
        var m = 65,
            x = 90,
            d = x - m + 1,
            s = x + m,
            o = [],
            n, i, c, e;

        for (i = 0, n = w.length; i<n; i++) {
            c = cca.call(w, i);
            e = s - c + h;
            e = e > x ? e - d : e;
            o.push(e);
        }
        return {
            o: w,
            d: o.join(''),
            e: fcc.apply(o, o),
        };
    }

    // return the parameter without a px suffix
    function noPx(num) {
        return Number(num.replace(/px$/, ''));
    }

    // return an element's given style property without px suffix
    function noPxStyle(elem, prop) {
        return Number(elem.style(prop).replace(/px$/, ''));
    }

    function endsWith(str, suffix) {
        return str.indexOf(suffix, str.length - suffix.length) !== -1;
    }

    // return true if the given debug flag was specified in the query params
    function debugOn(tag) {
        return debugFlags[tag];
    }

    // output debug message to console, if debug tag set...
    // e.g. fs.debug('mytag', arg1, arg2, ...)
    function debug(tag) {
        var args;
        if (debugOn(tag)) {
            args = Array.prototype.slice.call(arguments, 1);
            args.unshift('['+tag+']');
            $log.debug.apply(this, args);
        }
    }

    // trie operation
    function _trieOp(op, trie, word, data) {
        var p = trie,
            w = word.toUpperCase(),
            s = w.split(''),
            c = { p: p, s: s },
            t = [],
            x = 0,
            f1 = op === '+' ? add : probe,
            f2 = op === '+' ? insert : remove;

        function add(c) {
            var q = c.s.shift(),
                np = c.p[q];

            if (!np) {
                c.p[q] = {};
                np = c.p[q];
                x = 1;
            }
            return { p: np, s: c.s };
        }

        function probe(c) {
            var q = c.s.shift(),
                k = Object.keys(c.p).length,
                np = c.p[q];

            t.push({ q: q, k: k, p: c.p });
            if (!np) {
                t = [];
                return { s: [] };
            }
            return { p: np, s: c.s };
        }

        function insert() {
            c.p._data = data;
            return x ? 'added' : 'updated';
        }

        function remove() {
            if (t.length) {
                t = t.reverse();
                while (t.length) {
                    c = t.shift();
                    delete c.p[c.q];
                    if (c.k > 1) {
                        t = [];
                    }
                }
                return 'removed';
            }
            return 'absent';
        }

        while (c.s.length) {
            c = f1(c);
        }
        return f2();
    }

    // add word to trie (word will be converted to uppercase)
    // data associated with the word
    // returns 'added' or 'updated'
    function addToTrie(trie, word, data) {
        return _trieOp('+', trie, word, data);
    }

    // remove word from trie (word will be converted to uppercase)
    // returns 'removed' or 'absent'
    function removeFromTrie(trie, word) {
        return _trieOp('-', trie, word);
    }

    // lookup word (converted to uppercase) in trie
    // returns:
    //    undefined if the word is not in the trie
    //    -1 for a partial match (word is a prefix to an existing word)
    //    data for the word for an exact match
    function trieLookup(trie, word) {
        var s = word.toUpperCase().split(''),
            p = trie,
            n;

        while (s.length) {
            n = s.shift();
            p = p[n];
            if (!p) {
                return undefined;
            }
        }
        if (p._data) {
            return p._data;
        }
        return -1;
    }


    var hasOwn = {}.hasOwnProperty;

    function classNames() {
        var classes = [];

        for (var i = 0; i < arguments.length; i++) {
            var arg = arguments[i];
            if (!arg) continue;

            var argType = typeof arg;

            if (argType === 'string' || argType === 'number') {
                classes.push(arg);
            } else if (Array.isArray(arg)) {
                classes.push(classNames.apply(null, arg));
            } else if (argType === 'object') {
                for (var key in arg) {
                    if (hasOwn.call(arg, key) && arg[key]) {
                        classes.push(key);
                    }
                }
            }
        }

        return classes.join(' ');
    }

    function extend(protoProps, staticProps) {

        var parent = this,
            child;

        child = function () {
        return parent.apply(this, arguments);
        };

        angular.extend(child, parent, staticProps);

        // Set the prototype chain to inherit from `parent`, without calling
        // `parent`'s constructor function and add the prototype properties.
        child.prototype = angular.extend({}, parent.prototype, protoProps);
        child.prototype.constructor = child;

        // Set a convenience property in case the parent's prototype is needed
        // later.
        child.__super__ = parent.prototype;

        return child;
    }

    // -----------------------------------------------------------------
    // The next section deals with sanitizing external strings destined
    // to be loaded via a .html() function call.

    var matcher = /<\/?([a-zA-Z0-9]+)*(.*?)\/?>/igm,
        whitelist = ['b', 'i', 'p', 'em', 'strong', 'br'],
        evillist = ['script', 'style', 'iframe'];

    // Returns true if the tag is in the evil list, (and is not an end-tag)
    function inEvilList(tag) {
        return (evillist.indexOf(tag.name) !== -1 && tag.full.indexOf('/') === -1);
    }

    function analyze(html) {
        html = String(html) || '';

        var matches = [],
            match;

        // extract all tags
        while ((match = matcher.exec(html)) !== null) {
            matches.push({
                full: match[0],
                name: match[1],
                // NOTE: ignoring attributes {match[2].split(' ')} for now
            });
        }

        return matches;
    }

    function sanitize(html) {
        html = String(html) || '';

        var matches = analyze(html);

        // completely obliterate evil tags and their contents...
        evillist.forEach(function (tag) {
            var re = new RegExp('<' + tag + '(.*?)>(.*?[\r\n])*?(.*?)(.*?[\r\n])*?<\/' + tag + '>', 'gim');
            html = html.replace(re, '');
        });

        // filter out all but white-listed tags and end-tags
        matches.forEach(function (tag) {
            if (whitelist.indexOf(tag.name) === -1) {
                html = html.replace(tag.full, '');
                if (inEvilList(tag)) {
                    $log.warn('Unsanitary HTML input -- ' + tag.full + ' detected!');
                }
            }
        });

        // TODO: consider encoding HTML entities, e.g. '&' -> '&amp;'

        return html;
    }


    angular.module('onosUtil')
        .factory('FnService',
        ['$window', '$location', '$log', function (_$window_, $loc, _$log_) {
            $window = _$window_;
            $log = _$log_;

            _parseDebugFlags($loc.search().debug);

            return {
                isF: isF,
                isA: isA,
                isS: isS,
                isO: isO,
                contains: contains,
                areFunctions: areFunctions,
                areFunctionsNonStrict: areFunctionsNonStrict,
                windowSize: windowSize,
                isMobile: isMobile,
                isChrome: isChrome,
                isSafari: isSafari,
                isFirefox: isFirefox,
                debugOn: debugOn,
                debug: debug,
                find: find,
                inArray: inArray,
                removeFromArray: removeFromArray,
                isEmptyObject: isEmptyObject,
                sameObjProps: sameObjProps,
                containsObj: containsObj,
                cap: cap,
                eecode: eecode,
                noPx: noPx,
                noPxStyle: noPxStyle,
                endsWith: endsWith,
                addToTrie: addToTrie,
                removeFromTrie: removeFromTrie,
                trieLookup: trieLookup,
                classNames: classNames,
                extend: extend,
                sanitize: sanitize,
            };
    }]);

}());
