'use strict';

const isStandardSyntaxComment = require('../../utils/isStandardSyntaxComment');
const isWhitespace = require('../../utils/isWhitespace');
const report = require('../../utils/report');
const ruleMessages = require('../../utils/ruleMessages');
const validateOptions = require('../../utils/validateOptions');

const ruleName = 'comment-whitespace-inside';

const messages = ruleMessages(ruleName, {
	expectedOpening: 'Expected whitespace after "/*"',
	rejectedOpening: 'Unexpected whitespace after "/*"',
	expectedClosing: 'Expected whitespace before "*/"',
	rejectedClosing: 'Unexpected whitespace before "*/"',
});

/**
 * @param {import('postcss').Comment} comment
 */
function addWhitespaceBefore(comment) {
	if (comment.text.startsWith('*')) {
		comment.text = comment.text.replace(/^(\*+)/, `$1 `);
	} else {
		comment.raws.left = ' ';
	}
}

/**
 * @param {import('postcss').Comment} comment
 */
function addWhitespaceAfter(comment) {
	if (comment.text[comment.text.length - 1] === '*') {
		comment.text = comment.text.replace(/(\*+)$/, ` $1`);
	} else {
		comment.raws.right = ' ';
	}
}

/** @type {import('stylelint').Rule} */
const rule = (primary, _secondaryOptions, context) => {
	return (root, result) => {
		const validOptions = validateOptions(result, ruleName, {
			actual: primary,
			possible: ['always', 'never'],
		});

		if (!validOptions) {
			return;
		}

		root.walkComments((comment) => {
			if (!isStandardSyntaxComment(comment)) {
				return;
			}

			const rawComment = comment.toString();
			const firstFourChars = rawComment.substr(0, 4);

			// Return early if sourcemap or copyright comment
			if (/^\/\*[#!]\s/.test(firstFourChars)) {
				return;
			}

			const leftMatches = rawComment.match(/(^\/\*+)(\s)?/);

			if (leftMatches == null) throw new Error(`Invalid comment: "${rawComment}"`);

			const rightMatches = rawComment.match(/(\s)?(\*+\/)$/);

			if (rightMatches == null) throw new Error(`Invalid comment: "${rawComment}"`);

			const opener = leftMatches[1];
			const leftSpace = leftMatches[2] || '';
			const rightSpace = rightMatches[1] || '';
			const closer = rightMatches[2];

			if (primary === 'never' && leftSpace !== '') {
				complain(messages.rejectedOpening, opener.length);
			}

			if (primary === 'always' && !isWhitespace(leftSpace)) {
				complain(messages.expectedOpening, opener.length);
			}

			if (primary === 'never' && rightSpace !== '') {
				complain(messages.rejectedClosing, comment.toString().length - closer.length - 1);
			}

			if (primary === 'always' && !isWhitespace(rightSpace)) {
				complain(messages.expectedClosing, comment.toString().length - closer.length - 1);
			}

			/**
			 * @param {string} message
			 * @param {number} index
			 */
			function complain(message, index) {
				if (context.fix) {
					if (primary === 'never') {
						comment.raws.left = '';
						comment.raws.right = '';
						comment.text = comment.text.replace(/^(\*+)(\s+)?/, '$1').replace(/(\s+)?(\*+)$/, '$2');
					} else {
						if (!leftSpace) {
							addWhitespaceBefore(comment);
						}

						if (!rightSpace) {
							addWhitespaceAfter(comment);
						}
					}

					return;
				}

				report({
					message,
					index,
					result,
					ruleName,
					node: comment,
				});
			}
		});
	};
};

rule.ruleName = ruleName;
rule.messages = messages;
module.exports = rule;
