package optimizer

import (
	"strconv"
	"strings"
)

// parseHexOrDec parses an ACME-style number: $ff or 255.
// Returns -1 if s is not a parseable simple number (e.g. label references, <label, >label).
func parseHexOrDec(s string) int {
	if strings.HasPrefix(s, "$") {
		v, err := strconv.ParseUint(s[1:], 16, 16)
		if err != nil {
			return -1
		}
		return int(v)
	}
	// Strip trailing characters after the number (e.g., ",y" in "5,y")
	if idx := strings.IndexAny(s, ",)"); idx >= 0 {
		s = s[:idx]
	}
	v, err := strconv.ParseUint(s, 10, 16)
	if err != nil {
		return -1
	}
	return int(v)
}

// isSimpleNumber returns true if s is a plain hex/dec number (no label refs, <, >, etc.)
func isSimpleNumber(s string) bool {
	return parseHexOrDec(s) >= 0
}

type asmLine struct {
	text      string
	isLabel   bool
	isCode    bool
	isComment bool
	optMarker bool
	opcode    string
	operand   string
}

func parseLines(lines []string) []asmLine {
	var result []asmLine
	for _, l := range lines {
		al := asmLine{text: l}

		if l == "" {
			result = append(result, al)
			continue
		}

		if strings.HasPrefix(l, "; @@OPT:") {
			al.optMarker = true
			al.isComment = true
			result = append(result, al)
			continue
		}

		if strings.HasPrefix(l, ";") {
			al.isComment = true
			result = append(result, al)
			continue
		}

		if l[0] == '\t' {
			al.isCode = true
			parts := strings.Fields(l)
			if len(parts) > 0 {
				al.opcode = strings.ToLower(parts[0])
			}
			if len(parts) > 1 {
				al.operand = parts[1]
			}
		} else {
			al.isLabel = true
		}

		result = append(result, al)
	}
	return result
}

// stripOptMarkers removes @@OPT comment lines from the output
func stripOptMarkers(lines []asmLine) []asmLine {
	var result []asmLine
	for _, l := range lines {
		if l.optMarker {
			continue
		}
		result = append(result, l)
	}
	return result
}

func linesToString(lines []asmLine) []string {
	var result []string
	for _, l := range lines {
		result = append(result, l.text)
	}
	return result
}

// skipJmpMarker returns true if the line is an @@OPT comment (to be skipped in pass logic)
func skipJmpMarker(line asmLine) bool {
	return line.optMarker
}

