/*
	compiles a selector to an executable function
*/

module.exports = compile;
module.exports.compileUnsafe = compileUnsafe;
module.exports.compileToken = compileToken;

var parse       = require("css-what"),
    DomUtils    = require("domutils"),
    isTag       = DomUtils.isTag,
    Rules       = require("./general.js"),
    sortRules   = require("./sort.js"),
    BaseFuncs   = require("boolbase"),
    trueFunc    = BaseFuncs.trueFunc,
    falseFunc   = BaseFuncs.falseFunc,
    procedure   = require("./procedure.json");

function compile(selector, options, context){
	var next = compileUnsafe(selector, options, context);
	return wrap(next);
}

function wrap(next){
	return function base(elem){
		return isTag(elem) && next(elem);
	};
}

function compileUnsafe(selector, options, context){
	var token = parse(selector, options);
	return compileToken(token, options, context);
}

function includesScopePseudo(t){
    return t.type === "pseudo" && (
        t.name === "scope" || (
            Array.isArray(t.data) &&
            t.data.some(function(data){
                return data.some(includesScopePseudo);
            })
        )
    );
}

var DESCENDANT_TOKEN = {type: "descendant"},
    SCOPE_TOKEN = {type: "pseudo", name: "scope"},
    PLACEHOLDER_ELEMENT = {},
    getParent = DomUtils.getParent;

//CSS 4 Spec (Draft): 3.3.1. Absolutizing a Scope-relative Selector
//http://www.w3.org/TR/selectors4/#absolutizing
function absolutize(token, context){
    //TODO better check if context is document
    var hasContext = !!context && !!context.length && context.every(function(e){
        return e === PLACEHOLDER_ELEMENT || !!getParent(e);
    });


    token.forEach(function(t){
        if(t.length > 0 && isTraversal(t[0]) && t[0].type !== "descendant"){
            //don't return in else branch
        } else if(hasContext && !includesScopePseudo(t)){
            t.unshift(DESCENDANT_TOKEN);
        } else {
            return;
        }

        t.unshift(SCOPE_TOKEN);
    });
}

function compileToken(token, options, context){
    token = token.filter(function(t){ return t.length > 0; });

	token.forEach(sortRules);

	var isArrayContext = Array.isArray(context);

    context = (options && options.context) || context;

    if(context && !isArrayContext) context = [context];

    absolutize(token, context);

	return token
		.map(function(rules){ return compileRules(rules, options, context, isArrayContext); })
		.reduce(reduceRules, falseFunc);
}

function isTraversal(t){
	return procedure[t.type] < 0;
}

function compileRules(rules, options, context, isArrayContext){
	var acceptSelf = (isArrayContext && rules[0].name === "scope" && rules[1].type === "descendant");
	return rules.reduce(function(func, rule, index){
		if(func === falseFunc) return func;
		return Rules[rule.type](func, rule, options, context, acceptSelf && index === 1);
	}, options && options.rootFunc || trueFunc);
}

function reduceRules(a, b){
	if(b === falseFunc || a === trueFunc){
		return a;
	}
	if(a === falseFunc || b === trueFunc){
		return b;
	}

	return function combine(elem){
		return a(elem) || b(elem);
	};
}

//:not, :has and :matches have to compile selectors
//doing this in lib/pseudos.js would lead to circular dependencies,
//so we add them here

var Pseudos     = require("./pseudos.js"),
    filters     = Pseudos.filters,
    existsOne   = DomUtils.existsOne,
    isTag       = DomUtils.isTag,
    getChildren = DomUtils.getChildren;


function containsTraversal(t){
	return t.some(isTraversal);
}

filters.not = function(next, token, options, context){
	var opts = {
	    	xmlMode: !!(options && options.xmlMode),
	    	strict: !!(options && options.strict)
	    };

	if(opts.strict){
		if(token.length > 1 || token.some(containsTraversal)){
			throw new SyntaxError("complex selectors in :not aren't allowed in strict mode");
		}
	}

    var func = compileToken(token, opts, context);

	if(func === falseFunc) return next;
	if(func === trueFunc)  return falseFunc;

	return function(elem){
		return !func(elem) && next(elem);
	};
};

filters.has = function(next, token, options){
	var opts = {
		xmlMode: !!(options && options.xmlMode),
		strict: !!(options && options.strict)
	};

    //FIXME: Uses an array as a pointer to the current element (side effects)
    var context = token.some(containsTraversal) ? [PLACEHOLDER_ELEMENT] : null;

	var func = compileToken(token, opts, context);

	if(func === falseFunc) return falseFunc;
	if(func === trueFunc)  return function(elem){
			return getChildren(elem).some(isTag) && next(elem);
		};

	func = wrap(func);

    if(context){
        return function has(elem){
		return next(elem) && (
                (context[0] = elem), existsOne(func, getChildren(elem))
            );
	};
    }

    return function has(elem){
		return next(elem) && existsOne(func, getChildren(elem));
	};
};

filters.matches = function(next, token, options, context){
	var opts = {
		xmlMode: !!(options && options.xmlMode),
		strict: !!(options && options.strict),
		rootFunc: next
	};

	return compileToken(token, opts, context);
};
