/*=============================================================================#
 # Copyright (c) 2015, 2021 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.jcommons.text.core.input;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;


@NonNullByDefault
public abstract class FilterParserInput extends TextParserInput {
	
	
	private final TextParserInput source;
	
	private int[] bufferBeginIndexes;
	private int[] bufferEndIndexes;
	
	
	protected FilterParserInput(final TextParserInput source, final int defaultBufferSize) {
		super(defaultBufferSize);
		
		if (source == null) {
			throw new NullPointerException("source"); //$NON-NLS-1$
		}
		this.source= source;
		
		this.bufferBeginIndexes= new int[1];
		this.bufferEndIndexes= new int[0];
	}
	
	
	@Override
	protected void reset() {
		super.reset();
		
		this.bufferBeginIndexes[0]= 0;
	}
	
	
	@Override
	public FilterParserInput init() {
		super.init();
		
		return this;
	}
	
	@Override
	public FilterParserInput init(final int startIndex, final int stopIndex) {
		this.source.init(startIndex, stopIndex);
		
		this.bufferBeginIndexes[0]= this.source.getStartIndex();
		
		super.init(this.source.getStartIndex(), this.source.getStopIndex());
		
		return this;
	}
	
	
	public final TextParserInput getSource() {
		return this.source;
	}
	
	@Override
	protected int getSourceStartIndex() {
		return this.source.getSourceStartIndex();
	}
	
	@Override
	protected int getSourceLength() {
		return this.source.getSourceLength();
	}
	
	@Override
	protected @Nullable String getSourceString() {
		return this.source.getSourceString();
	}
	
	@Override
	protected int getSourceStringIndex() {
		return this.source.getSourceStringIndex();
	}
	
	
	@Override
	public final int getIndex(final int offset) {
		final int currentIdx= getIndexIdx();
		return this.bufferBeginIndexes[currentIdx + offset];
	}
	
	@Override
	public final int getLengthInSource(final int offset) {
		if (offset == 0) {
			return 0;
		}
		final int currentIdx= getIndexIdx();
		return this.bufferEndIndexes[currentIdx + offset - 1] - this.bufferBeginIndexes[currentIdx];
	}
	
	@Override
	public void consume(int offset) {
		if (offset == 0) {
			return;
		}
		int currentIdx= getIndexIdx();
		{	// we need bufferIndex for offset
			final int lastOffset= getEndIdx() - currentIdx - 1;
			if (offset > lastOffset) {
				if (lastOffset > 0x10) {
					setConsume(lastOffset, this.bufferBeginIndexes[currentIdx + lastOffset]);
					currentIdx= getIndexIdx();
					offset-= lastOffset;
				}
				if (!updateBuffer(offset + 1)) {
					checkOffset(offset);
					int index= getStopIndex();
					if (index == Integer.MIN_VALUE) {
						index= this.bufferBeginIndexes[getEndIdx()];
					}
					setConsume(offset, index);
					return;
				}
			}
		}
		setConsume(offset, this.bufferBeginIndexes[currentIdx + offset]);
	}
	
	
	@Override
	protected void doUpdateBuffer(final int index, final char[] buffer,
			final int requiredLength, final int recommendLength) {
		final int reused= copyBuffer0(buffer);
		final int[] begins= (buffer == getBuffer()) ? this.bufferBeginIndexes : new int[buffer.length + 1];
		final int[] ends= (buffer == getBuffer()) ? this.bufferEndIndexes : new int[buffer.length];
		final int currentIdx= getIndexIdx();
		if (reused > 0) {
			System.arraycopy(this.bufferBeginIndexes, currentIdx, begins, 0, reused + 1);
			System.arraycopy(this.bufferEndIndexes, currentIdx, ends, 0, reused);
		}
		else {
			begins[0]= this.bufferBeginIndexes[currentIdx];
		}
		
		final int end= read(this.source, buffer, begins, ends, reused, requiredLength, recommendLength);
		
		setBuffer(buffer, 0, end);
		this.bufferBeginIndexes= begins;
		this.bufferEndIndexes= ends;
		setConsume(0, this.bufferBeginIndexes[0]);
	}
	
	protected abstract int read(TextParserInput in, char[] buffer,
			int[] beginIndexes, int[] endIndexes,
			int beginIdx, int requiredEnd, int recommendEnd);
	
}
