// largely borrowed from Ractive – https://github.com/ractivejs/ractive/blob/2ec648aaf5296bb88c21812e947e0e42fcc456e3/src/Ractive/config/custom/css/transform.js
const selectorsPattern = /(?:^|\})?\s*([^\{\}]+)\s*\{/g;
const commentsPattern = /\/\*.*?\*\//g;
const selectorUnitPattern = /((?:(?:\[[^\]+]\])|(?:[^\s\+\>~:]))+)((?:::?[^\s\+\>\~\(:]+(?:\([^\)]+\))?)*\s*[\s\+\>\~]?)\s*/g;
const excludePattern = /^(?:@|\d+%)/;

function transformSelector ( selector, parent ) {
	const selectorUnits = [];
	let match;

	while ( match = selectorUnitPattern.exec( selector ) ) {
		selectorUnits.push({
			str: match[0],
			base: match[1],
			modifiers: match[2]
		});
	}

	// For each simple selector within the selector, we need to create a version
	// that a) combines with the id, and b) is inside the id
	const base = selectorUnits.map( unit => unit.str );

	const transformed = [];
	let i = selectorUnits.length;

	while ( i-- ) {
		const appended = base.slice();

		// Pseudo-selectors should go after the attribute selector
		const unit = selectorUnits[i];
		appended[i] = unit.base + parent + unit.modifiers || '';

		const prepended = base.slice();
		prepended[i] = parent + ' ' + prepended[i];

		transformed.push( appended.join( ' ' ), prepended.join( ' ' ) );
	}

	return transformed.join( ', ' );
}

export default function transformCss ( css, hash ) {
	const attr = `[svelte-${hash}]`;

	return css
		.replace( commentsPattern, '' )
		.replace( selectorsPattern, ( match, $1 ) => {
			// don't transform at-rules and keyframe declarations
			if ( excludePattern.test( $1 ) ) return match;

			const selectors = $1.split( ',' ).map( selector => selector.trim() );
			const transformed = selectors
				.map( selector => transformSelector( selector, attr ) )
				.join( ', ' ) + ' ';

			return match.replace( $1, transformed );
		});
}