/*
 * Copyright 2015-2022 the original author or authors.
 *
 * All rights reserved. This program and the accompanying materials are
 * made available under the terms of the Eclipse Public License v2.0 which
 * accompanies this distribution and is available at
 *
 * https://www.eclipse.org/legal/epl-v20.html
 */

package org.junit.platform.console;

import static java.lang.String.format;
import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.jupiter.api.Assertions.assertLinesMatch;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
import static org.junit.jupiter.api.DynamicContainer.dynamicContainer;
import static org.junit.jupiter.api.DynamicTest.dynamicTest;
import static org.junit.platform.commons.util.ReflectionUtils.findMethods;
import static org.junit.platform.commons.util.ReflectionUtils.getFullyQualifiedMethodName;

import java.io.File;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.DynamicNode;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestFactory;
import org.junit.jupiter.api.TestReporter;
import org.junit.jupiter.api.function.Executable;
import org.junit.platform.console.options.Details;
import org.junit.platform.console.options.Theme;
import org.opentest4j.TestAbortedException;

/**
 * @since 1.0
 */
class ConsoleDetailsTests {

	@TestFactory
	@DisplayName("Basic tests and annotations usage")
	List<DynamicNode> basic() {
		return scanContainerClassAndCreateDynamicTests(BasicTestCase.class);
	}

	@TestFactory
	@DisplayName("Skipped and disabled tests")
	List<DynamicNode> skipped() {
		return scanContainerClassAndCreateDynamicTests(SkipTestCase.class);
	}

	@TestFactory
	@DisplayName("Failed tests")
	List<DynamicNode> failed() {
		return scanContainerClassAndCreateDynamicTests(FailTestCase.class);
	}

	@TestFactory
	@DisplayName("Tests publishing report entries")
	List<DynamicNode> reports() {
		return scanContainerClassAndCreateDynamicTests(ReportTestCase.class);
	}

	private List<DynamicNode> scanContainerClassAndCreateDynamicTests(Class<?> containerClass) {
		var containerName = containerClass.getSimpleName().replace("TestCase", "");
		// String containerName = containerClass.getSimpleName();
		List<DynamicNode> nodes = new ArrayList<>();
		Map<Details, List<DynamicTest>> map = new EnumMap<>(Details.class);
		for (var method : findMethods(containerClass, m -> m.isAnnotationPresent(Test.class))) {
			var methodName = method.getName();
			var types = method.getParameterTypes();
			for (var details : Details.values()) {
				var tests = map.computeIfAbsent(details, key -> new ArrayList<>());
				for (var theme : Theme.values()) {
					var caption = containerName + "-" + methodName + "-" + details + "-" + theme;
					String[] args = { //
							"--include-engine", "junit-jupiter", //
							"--details", details.name(), //
							"--details-theme", theme.name(), //
							"--disable-ansi-colors", //
							"--disable-banner", //
							"--include-classname", containerClass.getCanonicalName(), //
							"--select-method", getFullyQualifiedMethodName(containerClass, methodName, types) //
					};
					var displayName = methodName + "() " + theme.name();
					var dirName = "console/details/" + containerName.toLowerCase();
					var outName = caption + ".out.txt";
					var runner = new Runner(dirName, outName, args);
					var source = toUri(dirName, outName).orElse(null);
					tests.add(dynamicTest(displayName, source, runner));
				}
			}
		}
		var source = new File("src/test/resources/console/details").toURI();
		map.forEach((details, tests) -> nodes.add(dynamicContainer(details.name(), source, tests.stream())));
		return nodes;
	}

	@DisplayName("Basic")
	static class BasicTestCase {

		@Test
		void empty() {
		}

		@Test
		@DisplayName(".oO fancy display name Oo.")
		void changeDisplayName() {
		}

	}

	@DisplayName("Skip")
	static class SkipTestCase {

		@Test
		@Disabled("single line skip reason")
		void skipWithSingleLineReason() {
		}

		@Test
		@Disabled("multi\nline\nfail\nmessage")
		void skipWithMultiLineMessage() {
		}

	}

	@DisplayName("Fail")
	static class FailTestCase {

		@Test
		void failWithSingleLineMessage() {
			fail("single line fail message");
		}

		@Test
		void failWithMultiLineMessage() {
			fail("multi\nline\nfail\nmessage");
		}

	}

	@DisplayName("Report")
	static class ReportTestCase {

		@Test
		void reportSingleMessage(TestReporter reporter) {
			reporter.publishEntry("foo");
		}

		@Test
		void reportMultipleMessages(TestReporter reporter) {
			reporter.publishEntry("foo");
			reporter.publishEntry("bar");
		}

		@Test
		void reportSingleEntryWithSingleMapping(TestReporter reporter) {
			reporter.publishEntry("foo", "bar");
		}

		@Test
		void reportMultiEntriesWithSingleMapping(TestReporter reporter) {
			reporter.publishEntry("foo", "bar");
			reporter.publishEntry("far", "boo");
		}

		@Test
		void reportMultiEntriesWithMultiMappings(TestReporter reporter) {
			Map<String, String> values = new LinkedHashMap<>();
			values.put("user name", "dk38");
			values.put("award year", "1974");
			reporter.publishEntry(values);
			reporter.publishEntry("single", "mapping");
			Map<String, String> more = new LinkedHashMap<>();
			more.put("user name", "st77");
			more.put("award year", "1977");
			more.put("last seen", "2001");
			reporter.publishEntry(more);
		}

	}

	private static class Runner implements Executable {

		private final String dirName;
		private final String outName;
		private final String[] args;

		private Runner(String dirName, String outName, String... args) {
			this.dirName = dirName;
			this.outName = outName;
			this.args = args;
		}

		@Override
		public void execute() throws Throwable {
			var wrapper = new ConsoleLauncherWrapper();
			var result = wrapper.execute(Optional.empty(), args);

			var optionalUri = toUri(dirName, outName);
			if (optionalUri.isEmpty()) {
				if (Boolean.getBoolean("org.junit.platform.console.ConsoleDetailsTests.writeResultOut")) {
					// do not use Files.createTempDirectory(prefix) as we want one folder for one container
					var temp = Paths.get(System.getProperty("java.io.tmpdir"), dirName.replace('/', '-'));
					Files.createDirectories(temp);
					var path = Files.writeString(temp.resolve(outName), result.out);
					throw new TestAbortedException(
						format("resource `%s` not found\nwrote console stdout to: %s/%s", dirName, outName, path));
				}
				fail("could not load resource named `" + dirName + "/" + outName + "`");
			}

			var path = Paths.get(optionalUri.get());
			assumeTrue(Files.exists(path), "path does not exist: " + path);
			assumeTrue(Files.isReadable(path), "can not read: " + path);

			var expectedLines = Files.readAllLines(path, UTF_8);
			var actualLines = List.of(result.out.split("\\R"));

			assertLinesMatch(expectedLines, actualLines);
		}
	}

	static Optional<URI> toUri(String dirName, String outName) {
		var resourceName = dirName + "/" + outName;
		var url = ConsoleDetailsTests.class.getClassLoader().getResource(resourceName);
		if (url == null) {
			return Optional.empty();
		}
		try {
			return Optional.of(url.toURI());
		}
		catch (URISyntaxException e) {
			return Optional.empty();
		}
	}

}
