this.Mediasite = this.Mediasite || {};
Mediasite.Player = Mediasite.Player || {};


Mediasite.Player.ApiOrigin = (function () {

    var Origin = function (scheme, host, port) {
        this.scheme = scheme;
        this.host = host;
        this.port = port;
    };
    Origin.prototype = {
        toString: function () {
            return this.scheme + '://' + this.host + ':' + this.port;
        }
    };

    var parseOrigin = function (originString) {
        var originPattern = /^(?:\s*)(\*|[a-z\d\-\+\.]+)(?:\:\/\/)([a-z\d\-\.]+)(?:\:{0,1})(\d*)(?:\s*)$/g;
        var universalOriginPattern = /^(?:\s*)\*(?:\s*)$/g;
        var matches;

        originString = originString && originString.toLowerCase();

        if (universalOriginPattern.test(originString)) {
            return getUniversalOrigin();
        }

        matches = originPattern.exec(originString);

        if (!matches) {
            return getNullOrigin();
        }

        return new Origin(matches[1], matches[2], matches[3]);
    };

    var getUniversalOrigin = function () {
        var o = new Origin('*', '*', '*');
        o.toString = function () { return '*'; };
        return o;
    };
    var isUniversalOrigin = function (origin) {
        return origin && origin.toString && origin.toString() === '*';
    };
    var getNullOrigin = function () {
        var o = new Origin('', '', '');
        o.toString = function () { return ''; };
        return o;
    };
    var isNullOrigin = function (origin) {
        return origin && origin.toString && origin.toString() === '';
    };


    var CompositeOriginMatcher = function () {
        var matchers = [];

        this.match = function (originStringToTest) {
            var i;
            for (i = 0; i < matchers.length; i += 1) {
                if (matchers[i].match(originStringToTest)) {
                    return true;
                }
            }

            return false;
        };


        this.addMatcher = function (matcher) {
            matchers.push(matcher);
        };
    }

    var StandardOriginMatcher = function (myOrigin) {
        var defaultPortLookup = { 'http': '80', 'https': '443' };

        this.match = function (otherOriginString) {
            var otherOrigin = parseOrigin(otherOriginString);
            var doPortsMatch = effectivePort(myOrigin) === effectivePort(otherOrigin);

            return myOrigin.scheme === otherOrigin.scheme && myOrigin.host === otherOrigin.host && doPortsMatch;
        };

        function effectivePort(origin) {
            if (typeof origin.port === 'string' && origin.port.length > 0) {
                return origin.port;
            }

            if (typeof defaultPortLookup[origin.scheme] === 'string') {
                return defaultPortLookup[origin.scheme];
            }

            return '';
        }
    };

    var BoringOriginMatcher = function (matchReturnValue) {
        this.match = function (otherOriginString) {
            return matchReturnValue;
        };
    };


    var createOriginMatcher = function (originString) {
        var origin;
        var matcher;
        var i, o, s;
        var wildcardSchemes = ['http', 'https'];

        origin = parseOrigin(originString);

        // Null origin -- return a matcher that NEVER matches.
        if (isNullOrigin(origin)) {
            return new BoringOriginMatcher(false);
        }

        // Universal origin -- return a matcher that ALWAYS matches.
        if (isUniversalOrigin(origin)) {
            return new BoringOriginMatcher(true);
        }


        // Wildcard Scheme -- return a composite matcher that will match all allowed schemes.
        if (origin.scheme === '*') {
            matcher = new CompositeOriginMatcher();
            for (i = 0; i < wildcardSchemes.length; i += 1) {
                o = new Origin(wildcardSchemes[i], origin.host, origin.port);
                s = o.toString();
                matcher.addMatcher(createOriginMatcher(s));
            }
            return matcher;
        }

        return new StandardOriginMatcher(origin);
    };

    var createOriginMatcherFromList = function (originArray) {
        var composite = new CompositeOriginMatcher();
        var originArray = originArray || [];
        var i, matcher;

        for (i = 0; i < originArray.length; i += 1) {
            matcher = createOriginMatcher(originArray[i]);
            composite.addMatcher(matcher);
        }

        return composite;
    };



    // Return this module's public API.

    return {
        parseOrigin: parseOrigin,
        isNullOrigin: isNullOrigin,
        isUniversalOrigin: isUniversalOrigin,
        StandardOriginMatcher: StandardOriginMatcher,
        CompositeOriginMatcher: CompositeOriginMatcher,
        createOriginMatcher: createOriginMatcher,
        createOriginMatcherFromList: createOriginMatcherFromList
    };

})();