/*******************************************************************************
 * Copyright (c) 2006, 2014 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/

package org.eclipse.jdt.internal.compiler.parser;

import org.eclipse.jdt.core.compiler.CharOperation;
import org.eclipse.jdt.core.compiler.InvalidInputException;

public class RecoveryScanner extends Scanner {
	public static final char[] FAKE_IDENTIFIER = "$missing$".toCharArray(); //$NON-NLS-1$

	private RecoveryScannerData data;

	private int[] pendingTokens;
	private int pendingTokensPtr = -1;
	private char[] fakeTokenSource = null;
	private boolean isInserted = true;
	private boolean precededByRemoved = false;
	private int skipNextInsertedTokens = -1;

	public boolean record = true;

	public RecoveryScanner(Scanner scanner, RecoveryScannerData data) {
		super(false,
				scanner.tokenizeWhiteSpace,
				scanner.checkNonExternalizedStringLiterals,
				scanner.sourceLevel,
				scanner.complianceLevel,
				scanner.taskTags,
				scanner.taskPriorities,
				scanner.isTaskCaseSensitive);
		setData(data);
	}
	
	public RecoveryScanner(
			boolean tokenizeWhiteSpace,
			boolean checkNonExternalizedStringLiterals,
			long sourceLevel,
			long complianceLevel,
			char[][] taskTags,
			char[][] taskPriorities,
			boolean isTaskCaseSensitive,
			RecoveryScannerData data) {
		super(false,
				tokenizeWhiteSpace,
				checkNonExternalizedStringLiterals,
				sourceLevel,
				complianceLevel,
				taskTags,
				taskPriorities,
				isTaskCaseSensitive);
		setData(data);
	}

	public void insertToken(int token, int completedToken, int position) {
		insertTokens(new int []{token}, completedToken, position);
	}

	private int[] reverse(int[] tokens) {
		int length = tokens.length;
		for(int i = 0, max = length / 2; i < max; i++) {
			int tmp = tokens[i];
			tokens[i] = tokens[length - i - 1];
			tokens[length - i - 1] = tmp;
		}
		return tokens;
	}
	public void insertTokens(int[] tokens, int completedToken, int position) {
		if(!this.record) return;

		if(completedToken > -1 && Parser.statements_recovery_filter[completedToken] != 0) return;

		this.data.insertedTokensPtr++;
		if(this.data.insertedTokens == null) {
			this.data.insertedTokens = new int[10][];
			this.data.insertedTokensPosition = new int[10];
			this.data.insertedTokenUsed = new boolean[10];
		} else if(this.data.insertedTokens.length == this.data.insertedTokensPtr) {
			int length = this.data.insertedTokens.length;
			System.arraycopy(this.data.insertedTokens, 0, this.data.insertedTokens = new int[length * 2][], 0, length);
			System.arraycopy(this.data.insertedTokensPosition, 0, this.data.insertedTokensPosition = new int[length * 2], 0, length);
			System.arraycopy(this.data.insertedTokenUsed, 0, this.data.insertedTokenUsed = new boolean[length * 2], 0, length);
		}
		this.data.insertedTokens[this.data.insertedTokensPtr] = reverse(tokens);
		this.data.insertedTokensPosition[this.data.insertedTokensPtr] = position;
		this.data.insertedTokenUsed[this.data.insertedTokensPtr] = false;
	}
	
	public void insertTokenAhead(int token, int index) {
		if(!this.record) return;

		int length = this.data.insertedTokens[index].length;
		int [] tokens = new int [length + 1];
		System.arraycopy(this.data.insertedTokens[index], 0, tokens, 1, length);
		tokens[0] = token;
		this.data.insertedTokens[index] = tokens;
	}

	public void replaceTokens(int token, int start, int end) {
		replaceTokens(new int []{token}, start, end);
	}

	public void replaceTokens(int[] tokens, int start, int end) {
		if(!this.record) return;
		this.data.replacedTokensPtr++;
		if(this.data.replacedTokensStart == null) {
			this.data.replacedTokens = new int[10][];
			this.data.replacedTokensStart = new int[10];
			this.data.replacedTokensEnd = new int[10];
			this.data.replacedTokenUsed= new boolean[10];
		} else if(this.data.replacedTokensStart.length == this.data.replacedTokensPtr) {
			int length = this.data.replacedTokensStart.length;
			System.arraycopy(this.data.replacedTokens, 0, this.data.replacedTokens = new int[length * 2][], 0, length);
			System.arraycopy(this.data.replacedTokensStart, 0, this.data.replacedTokensStart = new int[length * 2], 0, length);
			System.arraycopy(this.data.replacedTokensEnd, 0, this.data.replacedTokensEnd = new int[length * 2], 0, length);
			System.arraycopy(this.data.replacedTokenUsed, 0, this.data.replacedTokenUsed = new boolean[length * 2], 0, length);
		}
		this.data.replacedTokens[this.data.replacedTokensPtr] = reverse(tokens);
		this.data.replacedTokensStart[this.data.replacedTokensPtr] = start;
		this.data.replacedTokensEnd[this.data.replacedTokensPtr] = end;
		this.data.replacedTokenUsed[this.data.replacedTokensPtr] = false;
	}

	public void removeTokens(int start, int end) {
		if(!this.record) return;
		this.data.removedTokensPtr++;
		if(this.data.removedTokensStart == null) {
			this.data.removedTokensStart = new int[10];
			this.data.removedTokensEnd = new int[10];
			this.data.removedTokenUsed = new boolean[10];
		} else if(this.data.removedTokensStart.length == this.data.removedTokensPtr) {
			int length = this.data.removedTokensStart.length;
			System.arraycopy(this.data.removedTokensStart, 0, this.data.removedTokensStart = new int[length * 2], 0, length);
			System.arraycopy(this.data.removedTokensEnd, 0, this.data.removedTokensEnd = new int[length * 2], 0, length);
			System.arraycopy(this.data.removedTokenUsed, 0, this.data.removedTokenUsed = new boolean[length * 2], 0, length);
		}
		this.data.removedTokensStart[this.data.removedTokensPtr] = start;
		this.data.removedTokensEnd[this.data.removedTokensPtr] = end;
		this.data.removedTokenUsed[this.data.removedTokensPtr] = false;
	}

	@Override
	protected int getNextToken0() throws InvalidInputException {
		if(this.pendingTokensPtr > -1) {
			int pendingToken = this.pendingTokens[this.pendingTokensPtr--];
			if(pendingToken == TerminalTokens.TokenNameIdentifier){
				this.fakeTokenSource = FAKE_IDENTIFIER;
			} else {
				this.fakeTokenSource = CharOperation.NO_CHAR;
			}
			return pendingToken;
		}

		this.fakeTokenSource = null;
		this.precededByRemoved = false;

		if(this.data.insertedTokens != null) {
			for (int i = 0; i <= this.data.insertedTokensPtr; i++) {
				if(this.data.insertedTokensPosition[i] == this.currentPosition - 1 && i > this.skipNextInsertedTokens) {
					this.data.insertedTokenUsed[i] = true;
					this.pendingTokens = this.data.insertedTokens[i];
					this.pendingTokensPtr = this.data.insertedTokens[i].length - 1;
					this.isInserted = true;
					this.startPosition = this.currentPosition;
					this.skipNextInsertedTokens = i;
					int pendingToken = this.pendingTokens[this.pendingTokensPtr--];
					if(pendingToken == TerminalTokens.TokenNameIdentifier){
						this.fakeTokenSource = FAKE_IDENTIFIER;
					} else {
						this.fakeTokenSource = CharOperation.NO_CHAR;
					}
					return pendingToken;
				}
			}
			this.skipNextInsertedTokens = -1;
		}

		int previousLocation = this.currentPosition;
		int currentToken = super.getNextToken0();

		if(this.data.replacedTokens != null) {
			for (int i = 0; i <= this.data.replacedTokensPtr; i++) {
				if(this.data.replacedTokensStart[i] >= previousLocation &&
						this.data.replacedTokensStart[i] <= this.startPosition &&
						this.data.replacedTokensEnd[i] >= this.currentPosition - 1) {
					this.data.replacedTokenUsed[i] = true;
					this.pendingTokens = this.data.replacedTokens[i];
					this.pendingTokensPtr = this.data.replacedTokens[i].length - 1;
					this.fakeTokenSource = FAKE_IDENTIFIER;
					this.isInserted = false;
					this.currentPosition = this.data.replacedTokensEnd[i] + 1;
					int pendingToken = this.pendingTokens[this.pendingTokensPtr--];
					if(pendingToken == TerminalTokens.TokenNameIdentifier){
						this.fakeTokenSource = FAKE_IDENTIFIER;
					} else {
						this.fakeTokenSource = CharOperation.NO_CHAR;
					}
					return pendingToken;
				}
			}
		}
		if(this.data.removedTokensStart != null) {
			for (int i = 0; i <= this.data.removedTokensPtr; i++) {
				if(this.data.removedTokensStart[i] >= previousLocation &&
						this.data.removedTokensStart[i] <= this.startPosition &&
						this.data.removedTokensEnd[i] >= this.currentPosition - 1) {
					this.data.removedTokenUsed[i] = true;
					this.currentPosition = this.data.removedTokensEnd[i] + 1;
					this.precededByRemoved = false;
					return getNextToken0();
				}
			}
		}
		return currentToken;
	}

	@Override
	public char[] getCurrentIdentifierSource() {
		if(this.fakeTokenSource != null) return this.fakeTokenSource;
		return super.getCurrentIdentifierSource();
	}

	@Override
	public char[] getCurrentTokenSourceString() {
		if(this.fakeTokenSource != null) return this.fakeTokenSource;
		return super.getCurrentTokenSourceString();
	}

	@Override
	public char[] getCurrentTokenSource() {
		if(this.fakeTokenSource != null) return this.fakeTokenSource;
		return super.getCurrentTokenSource();
	}

	public RecoveryScannerData getData() {
		return this.data;
	}

	public boolean isFakeToken() {
		return this.fakeTokenSource != null;
	}

	public boolean isInsertedToken() {
		return this.fakeTokenSource != null && this.isInserted;
	}

	public boolean isReplacedToken() {
		return this.fakeTokenSource != null && !this.isInserted;
	}

	public boolean isPrecededByRemovedToken() {
		return this.precededByRemoved;
	}

	public void setData(RecoveryScannerData data) {
		if(data == null) {
			this.data = new RecoveryScannerData();
		} else {
			this.data = data;
		}
	}

	public void setPendingTokens(int[] pendingTokens) {
		this.pendingTokens = pendingTokens;
		this.pendingTokensPtr = pendingTokens.length - 1;
	}
}
