package parser

import "../token"
import "core:strings"

push_token :: proc(
	parent: ^token.Token,
	type: token.TokenType,
	value: token.TokenValue = nil,
) -> ^token.Token {
	tok := new(token.Token)
	tok^ = token.Token{type, value, nil, parent}
	append(&parent.children, tok)
	return tok
}

is_space_byte :: proc(b: byte) -> bool {
	return b == ' ' || b == '\t'
}

parse_header :: proc(line: string) -> (int, string) {
	if len(line) == 0 {
		return 0, line
	}

	lvl := 0
	for lvl < len(line) && line[lvl] == '!' {
		lvl += 1
	}
	if lvl == 0 || lvl >= len(line) || line[lvl] != ' ' {
		return 0, line
	}
	return lvl, line[lvl + 1:]
}

parse_footnote_def :: proc(line: string) -> (string, string, bool) {
	if strings.has_prefix(line, "[&&") {
		idx := strings.index_byte(line, ']')
		if idx != -1 {
			id := line[3:idx]
			text := strings.trim_space(line[idx + 1:])
			return id, text, true
		}
	}
	return "", "", false
}

push_text :: proc(parent: ^token.Token, text: string) {
	align_type, has_align := get_alignment_token(text)
	cleaned := strip_alignment_markers(text)

	target := parent
	if has_align {
		target = push_token(parent, align_type, nil)
	}
	push_token(target, token.TokenType.Text, cleaned)
}

push_text_line :: proc(target: ^token.Token, text: string) {
	if len(target.children) > 0 {
		br := new(token.Token)
		br^ = token.Token{token.TokenType.BreakLine, nil, nil, target}
		append(&target.children, br)
	}
	push_text(target, text)
}

get_alignment_token :: proc(text: string) -> (token.TokenType, bool) {
	trimmed := strings.trim_space(text)
	if len(trimmed) == 0 {
		return .Text, false
	}
	if strings.has_suffix(trimmed, ">>") || strings.has_prefix(trimmed, ">>") {
		return .Right, true
	}
	if strings.has_suffix(trimmed, "<<") || strings.has_prefix(trimmed, "<<") {
		return .Left, true
	}
	if strings.has_suffix(trimmed, "^^") || strings.has_prefix(trimmed, "^^") {
		return .Middle, true
	}
	return .Text, false
}

strip_alignment_markers :: proc(text: string) -> string {
	trimmed := strings.trim_space(text)
	if strings.has_suffix(trimmed, ">>") {
		return strings.trim_space(trimmed[:len(trimmed) - 2])
	}
	if strings.has_prefix(trimmed, ">>") {
		return strings.trim_space(trimmed[2:])
	}
	if strings.has_suffix(trimmed, "<<") {
		return strings.trim_space(trimmed[:len(trimmed) - 2])
	}
	if strings.has_prefix(trimmed, "<<") {
		return strings.trim_space(trimmed[2:])
	}
	if strings.has_suffix(trimmed, "^^") {
		return strings.trim_space(trimmed[:len(trimmed) - 2])
	}
	if strings.has_prefix(trimmed, "^^") {
		return strings.trim_space(trimmed[2:])
	}
	return trimmed
}
