/*=============================================================================#
 # 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 static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

import org.junit.jupiter.api.Test;

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


@NonNullByDefault
public class OffsetStringParserInputTest extends AbstractTextParserInputTest<OffsetStringParserInput> {
	
	
	public OffsetStringParserInputTest() {
	}
	
	
	@Test
	public void initRegion() {
		final String s= Utils.COUNTER_STRING.substring(0, 800);
		this.input= new OffsetStringParserInput(s.substring(50), 50);
		this.input.init(100, 200);
		
		assertEquals(100, this.input.getStartIndex());
		assertEquals(200, this.input.getStopIndex());
	}
	
	@Test
	public void initRegionIllegalStart() {
		final String s= Utils.COUNTER_STRING.substring(0, 800);
		this.input= new OffsetStringParserInput(s.substring(50), 50);
		assertThrows(IndexOutOfBoundsException.class,
				() -> this.input.init(49, 400) );
	}
	
	@Test
	public void initRegionIllegalStop() {
		final String s= Utils.COUNTER_STRING.substring(0, 800);
		this.input= new OffsetStringParserInput(s.substring(50), 50);
		assertThrows(IndexOutOfBoundsException.class,
				() -> this.input.init(50, 801) );
	}
	
	@Test
	public void initRegionIllegalLength() {
		final String s= Utils.COUNTER_STRING.substring(0, 800);
		this.input= new OffsetStringParserInput(s.substring(50), 50);
		assertThrows(IllegalArgumentException.class,
				() -> this.input.init(800, 400) );
	}
	
	public void initNegativIndex() {
		final String s= Utils.COUNTER_STRING.substring(0, 800);
		this.input= new OffsetStringParserInput(s, -50);
		this.input.init(-50, 750);
	}
	
	@Test
	public void initNegativIndexInvalidStart() {
		final String s= Utils.COUNTER_STRING.substring(0, 800);
		this.input= new OffsetStringParserInput(s, -50);
		assertThrows(IndexOutOfBoundsException.class,
				() -> this.input.init(-51, 750) );
	}
	
	@Test
	public void initNegativIndexInvalidStop() {
		final String s= Utils.COUNTER_STRING.substring(0, 800);
		this.input= new OffsetStringParserInput(s, -50);
		assertThrows(IndexOutOfBoundsException.class,
				() -> this.input.init(-50, 751) );
	}
	
	@Test
	public void read() {
		final String s= Utils.COUNTER_STRING.substring(0, 800);
		this.input= new OffsetStringParserInput(s.substring(50), 50);
		this.input.init(50, 800);
		
		assertChars(s, 50, 800);
		
		assertEquals(TextParserInput.EOF, this.input.get(s.length()));
		assertEquals(TextParserInput.EOF, this.input.get(s.length() + 0x10000));
		
		assertEquals(s.length() - 50, this.input.getBuffer().length);
	}
	
	@Test
	public void readRegion() {
		final String s= Utils.COUNTER_STRING.substring(0, 800);
		this.input= new OffsetStringParserInput(s.substring(50), 50);
		this.input.init(100, 200);
		
		assertChars(s, 100, 200);
		
		assertEquals(TextParserInput.EOF, this.input.get(200));
		
		assertEquals(s.length() - 50, this.input.getBuffer().length);
	}
	
	@Test
	public void updateBuffer() {
		final String s= Utils.COUNTER_STRING;
		this.input= new OffsetStringParserInput(s.substring(50), 50);
		this.input.init(50, s.length());
		
		readConsume(s, 50, s.length(), 100);
		
		assertEquals(TextParserInput.EOF, this.input.get(0));
		
		assertEquals(TextParserInput.DEFAULT_BUFFER_SIZE, this.input.getBuffer().length);
	}
	
	@Test
	public void increaseBuffer() {
		final String s= Utils.COUNTER_STRING;
		this.input= new OffsetStringParserInput(s.substring(50), 50);
		this.input.init(50, s.length());
		
		assertChars(s, 50, s.length());
		// check increased buffer completely:
		assertChars(s, 50, s.length());
		
		assertEquals(TextParserInput.EOF, this.input.get(s.length()));
	}
	
	@Test
	public void consume1() {
		final String s= Utils.COUNTER_STRING;
		this.input= new OffsetStringParserInput(s.substring(50), 50);
		this.input.init(50, s.length());
		
		readConsume(s, 50, s.length(), 1);
		
		assertEquals(TextParserInput.EOF, this.input.get(0));
	}
	
	@Test
	public void combined() {
		final String s= Utils.COUNTER_STRING;
		this.input= new OffsetStringParserInput(s.substring(50), 50);
		this.input.init(50, s.length());
		
		readConsume(s, 50, s.length(), 2351);
		
		assertEquals(TextParserInput.EOF, this.input.get(0));
		
		assertTrue(0x1000 >= this.input.getBuffer().length);
	}
	
	@Test
	public void empty() {
		final String s= "";
		this.input= new OffsetStringParserInput(s, 50);
		this.input.init(50, 50);
		
		assertEquals(TextParserInput.EOF, this.input.get(0));
	}
	
}
