import { ExternalTokenizer } from '@lezer/lr'
import { JavascriptExpression, Text } from './ejs.parser.terms.js'

const percent = 37
const closeAngle = 62
const dash = 45
const underscore = 95
const openAngle = 60

export const javascriptExpressionOrText = new ExternalTokenizer(
  (input, stack) => {
    let { next } = input
    const start = input.pos

    while (next !== -1) {
      if (next === openAngle && input.peek(1) === percent) break
      if (
        ([dash, underscore].includes(next) &&
          input.peek(1) === percent &&
          input.peek(2) === closeAngle) ||
        (next === percent && input.peek(1) === closeAngle)
      ) {
        break
      }
      next = input.advance()
    }

    if (stack.canShift(JavascriptExpression)) {
      // Empty expressions are valid: <% %>
      input.acceptToken(JavascriptExpression)
    } else if (stack.canShift(Text) && input.pos > start) {
      // Never emit empty Text — that loops forever at EOF
      input.acceptToken(Text)
    }
  },
  { contextual: true }
)
