'use strict';

// State machine states reused between parses for better perf
const STATES = {
  NORMAL: 0,
  IN_SINGLE_QUOTE: 1,
  IN_DOUBLE_QUOTE: 2,
  IN_COMMENT: 3,
};

/**
 * CSS Comment Parser with context awareness
 * Properly handles comments inside strings, URLs, and escaped characters
 *
 * @param {string} input
 * @return {[number, number, number][]}
 */
module.exports = function commentParser(input) {
  /** @type {[number, number, number][]} */
  const tokens = [];
  const length = input.length;
  let pos = 0;

  let state = STATES.NORMAL;
  let tokenStart = 0;
  let commentStart = 0;

  while (pos < length) {
    const char = input[pos];
    const nextChar = pos + 1 < length ? input[pos + 1] : '';

    switch (state) {
      case STATES.NORMAL:
        if (char === '/' && nextChar === '*') {
          // Found comment start - add non-comment token if needed
          if (pos > tokenStart) {
            tokens.push([0, tokenStart, pos]);
          }
          commentStart = pos;
          state = STATES.IN_COMMENT;
          pos += 2; // Skip /*
          continue;
        } else if (char === '"') {
          state = STATES.IN_DOUBLE_QUOTE;
        } else if (char === "'") {
          state = STATES.IN_SINGLE_QUOTE;
        }
        break;

      case STATES.IN_SINGLE_QUOTE:
        if (char === '\\' && nextChar) {
          // Skip escaped character
          pos += 2;
          continue;
        } else if (char === "'") {
          state = STATES.NORMAL;
        }
        break;

      case STATES.IN_DOUBLE_QUOTE:
        if (char === '\\' && nextChar) {
          // Skip escaped character
          pos += 2;
          continue;
        } else if (char === '"') {
          state = STATES.NORMAL;
        }
        break;

      case STATES.IN_COMMENT:
        if (char === '*' && nextChar === '/') {
          // Found comment end
          tokens.push([1, commentStart + 2, pos]);
          tokenStart = pos + 2;
          state = STATES.NORMAL;
          pos += 2; // Skip */
          continue;
        }
        break;
    }

    pos++;
  }

  // Handle remaining content
  if (state === STATES.IN_COMMENT) {
    // Unclosed comment - treat as comment to end
    tokens.push([1, commentStart + 2, length]);
  } else if (tokenStart < length) {
    // Add final non-comment token
    tokens.push([0, tokenStart, length]);
  }

  return tokens;
};
