// Splits and parses the YAML frontmatter block from Markdown source files.

const OPEN = '---\n'       // 4 chars
const CLOSE = '\n---\n'    // 5 chars

// Splits a markdown source into { frontmatter, body }; both are empty strings when no YAML frontmatter block is found.
export function splitFrontmatter(source) {
  if (!source.startsWith(OPEN)) return { frontmatter: '', body: source }
  const end = source.indexOf(CLOSE, OPEN.length)
  if (end === -1) return { frontmatter: '', body: source }
  return { frontmatter: source.slice(OPEN.length, end), body: source.slice(end + CLOSE.length) }
}

// Parses a YAML frontmatter string into a plain object, handling scalars, booleans, numbers, arrays, and one level of nesting.
export function parseFrontmatter(text) {
  const result = {}
  let nestedKey = null
  for (const raw of text.split('\n')) {
    const line = raw.trimEnd()
    if (!line || line.startsWith('#')) continue
    if (/^\s+/.test(line) && nestedKey) {
      const match = line.match(/^\s+([\w-]+):\s*(.*)$/)
      if (match) {
        if (typeof result[nestedKey] !== 'object' || result[nestedKey] === null) result[nestedKey] = {}
        result[nestedKey][match[1]] = parseValue(match[2])
      }
      continue
    }
    const match = line.match(/^([\w-]+):\s*(.*)$/)
    if (!match) continue
    const [, key, value] = match
    nestedKey = value === '' ? key : null
    result[key] = value === '' ? {} : parseValue(value)
  }
  return result
}

// Coerces a raw YAML value string to boolean, number, inline array, quoted string, or plain string.
function parseValue(raw) {
  if (raw === 'true') return true
  if (raw === 'false') return false
  if (raw === '') return ''
  if (/^-?\d+(\.\d+)?$/.test(raw)) return Number(raw)
  if (raw.startsWith('[') && raw.endsWith(']')) {
    return raw.slice(1, -1).split(',').map((s) => parseValue(s.trim()))
  }
  if (raw.startsWith("'") && raw.endsWith("'")) return raw.slice(1, -1).replace(/''/g, "'")
  if (raw.startsWith('"') && raw.endsWith('"')) return raw.slice(1, -1)
  return raw
}
