'use strict'

var slugify = require('slugify')
var escaper = require('escaper')
var stripComments = require('strip-css-comments')

module.exports = scope
scope.replace = replace

function scope (css, parent, o) {
	if (!css) return css

	if (!parent) return css

	if (typeof o === 'string') o = {keyframes: o}
	if (!o) o = {keyframes: false}

	css = replace(css, parent + ' $1$2')

	//regexp.escape
	var parentRe = parent.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&')

	//replace self-selectors
	css = css.replace(new RegExp('(' + parentRe + ')\\s*\\1(?=[\\s\\r\\n,{])', 'g'), '$1')

	//replace `:host` with parent
	css = css.replace(new RegExp('(' + parentRe + ')\\s*:host', 'g'), '$1')

	//revoke wrongly replaced @ statements, like @supports, @import, @media etc.
	css = css.replace(new RegExp('(' + parentRe + ')\\s*@', 'g'), '@')

	//revoke wrongly replaced :root blocks
	css = css.replace(new RegExp('(' + parentRe + ')\\s*:root', 'g'), ':root')

	//animations: prefix animation anmes
	var animations = [],
	    animationNameRe = /@keyframes\s+([a-zA-Z0-9_-]+)\s*{/g,
	    match
	while ((match = animationNameRe.exec(css)) !== null) {
		if (animations.indexOf(match[1]) < 0)
			animations.push(match[1])
	}

	var slug = slugify(parent)

	animations.forEach(function (name) {
		var newName = (o.keyframes === true ? slug + '-' : typeof o.keyframes === 'string' ? o.keyframes : '') + name
		css = css.replace(new RegExp('(@keyframes\\s+)' + name + '(\\s*{)', 'g'),
				  '$1' + newName + '$2')
		css = css.replace(new RegExp('(animation(?:-name)?\\s*:[^;]*\\s*)' + name + '([\\s;}])', 'g'),
				  '$1' + newName + '$2')
	})
 	//animation: revoke wrongly replaced keyframes
	css = css.replace(new RegExp('(' + parentRe + ' )(\\s*(?:to|from|[+-]?(?:(?:\\.\\d+)|(?:\\d+(?:\\.\\d*)?))%))(?=[\\s\\r\\n,{])', 'g'), '$2')

	return css
}

function replace (css, replacer) {
	var arr = []

	css = stripComments(css)

	// escape strings etc.
	css = escaper.replace(css, true, arr)

	css = css.replace(/([^\r\n,{}]+)(,(?=[^}]*{)|\s*{)/g, replacer)

	// insert comments, strings etc. back
	css = escaper.paste(css, arr)

	return css
}

