// SPDX-License-Identifier: Apache-2.0
/*
 * Copyright 2025-2026 Richard Lesh
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package cloud.lesh.CPUSim64;

import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.misc.Interval;

import java.util.List;

public final class CollectingErrorListener extends BaseErrorListener {
	private List<String> errors;
	HasLocation locator;
	public CollectingErrorListener(List<String> errors, HasLocation locator) {
		this.errors = errors;
		this.locator = locator;
	}

	@Override
	public void syntaxError(Recognizer<?, ?> recognizer,
							Object offendingSymbol,
							int line,
							int charPositionInLine,
							String msg,
							RecognitionException e) {

		// Try to extract a helpful offending text (works for both lexer & parser)
		String offendingText = "";
		if (e instanceof LexerNoViableAltException lexNoAlt) {
			// Lexer error: pull the single character (or span) that caused it
			CharStream cs = ((Lexer) recognizer).getInputStream();
			int start = lexNoAlt.getStartIndex();
			int stop  = Math.min(start, cs.size() - 1);
			offendingText = cs.getText(Interval.of(start, stop));
		} else if (offendingSymbol instanceof Token tok) {
			// Parser error: token text is available
			offendingText = tok.getText();
		}

		String formatted;
		if (locator == null ) {
			formatted = String.format("Preprocessed line %d:%d:ERROR:%s",
				line, charPositionInLine, msg);
		} else {
			formatted = String.format("%s:%d:ERROR:%s",
					locator.getLocation(line), charPositionInLine, msg);
		}
		errors.add(formatted);
	}

	private static String escape(String s) {
		return s.replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t");
	}
}
