package eu.simstadt.regionchooser;

import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach; // JUnit 5
import org.junit.jupiter.api.BeforeEach; // JUnit 5
import org.junit.jupiter.api.Test;
import picocli.CommandLine;


class RegionChooserCommandLineInterfaceTest
{
	final PrintStream originalOut = System.out;
	final PrintStream originalErr = System.err;
	final ByteArrayOutputStream out = new ByteArrayOutputStream();
	final ByteArrayOutputStream err = new ByteArrayOutputStream();

	private static final Path TEST_REPOSITORY = Paths.get("src/test/resources/testdata/");

	@BeforeEach
	public void setUpStreams() {
		out.reset();
		err.reset();
		System.setOut(new PrintStream(out));
		System.setErr(new PrintStream(err));
	}

	@AfterEach
	public void restoreStreams() {
		System.setOut(originalOut);
		System.setErr(originalErr);
	}

	@Test
	void testNoInput() {
		new CommandLine(new RegionChooserCommandLineInterface()).execute("");
		//		originalOut.println(err.toString());
		String expectedErr = "Missing required options: '--input=input.gml', '--output=output.gml', '--wkt=polygon.wkt'";
		assertTrue(err.toString().contains(expectedErr), err.toString() + " should contain " + expectedErr);
	}

	@Test
	void testExtractRegionFromTwoCitygmls() throws IOException {
		String wktPolygon = "POLYGON((3512984.7003764412 5405148.310572891,3513038.6360455155 5405010.072163861,3513142.7277745553 5405004.02571992,3514204.1661769524 5405563.192081669,3514399.2818417274 5405720.905457244,3514291.6158155007 5405896.706492759,3512984.7003764412 5405148.310572891))";
		Path citygml1 = TEST_REPOSITORY.resolve("Stuttgart.proj/Stuttgart_LOD0_LOD1_small.gml");
		Path citygml2 = TEST_REPOSITORY.resolve("Stuttgart.proj/Stöckach_überarbeitete GML-NoBuildingPart.gml");
		Path outGML = Files.createTempFile("output", ".gml");
		Path inWKT = Files.createTempFile("polygon", ".wkt");
		try (BufferedWriter wkt = Files.newBufferedWriter(inWKT)) {
			wkt.write(wktPolygon);
		}
		new CommandLine(new RegionChooserCommandLineInterface()).execute("--input=" + citygml1 + "," + citygml2,
				"--output=" + outGML, "--wkt=" + inWKT, "--epsg=31463", "--local");
		String expectedLog = "Buildings found in selected region 20";
		assertTrue(err.toString().contains(expectedLog), err.toString() + " should contain " + expectedLog);
		assertTrue(Files.size(outGML) > 600_000);
	}


	@Test
	void testExtractRegionFromTwoCitygmlsInWGS84() throws IOException {
		String wktPolygon = "POLYGON((9.18991539528286 48.79067456353269, 9.195580220722313 48.7873947720947, 9.172062612079735 48.78241812742368, 9.170946813129538 48.78569824412753, 9.18991539528286 48.79067456353269))";
		Path citygml1 = TEST_REPOSITORY.resolve("Stuttgart.proj/Stuttgart_LOD0_LOD1_small.gml");
		Path citygml2 = TEST_REPOSITORY.resolve("Stuttgart.proj/Stöckach_überarbeitete GML-NoBuildingPart.gml");
		Path outGML = Files.createTempFile("output", ".gml");
		Path inWKT = Files.createTempFile("polygon", ".wkt");
		try (BufferedWriter wkt = Files.newBufferedWriter(inWKT)) {
			wkt.write(wktPolygon);
		}
		new CommandLine(new RegionChooserCommandLineInterface()).execute("--input=" + citygml1 + "," + citygml2,
				"--output=" + outGML, "--wkt=" + inWKT);
		originalOut.println(err.toString());
		String expectedLog = "EPSG:31463";
		assertTrue(err.toString().contains(expectedLog), err.toString() + " should contain " + expectedLog);
		expectedLog = "Buildings found in selected region 22";
		assertTrue(err.toString().contains(expectedLog), err.toString() + " should contain " + expectedLog);
		assertTrue(Files.size(outGML) > 300_000);
	}
	//TODO: Test with stdin
}

