package net.sf.latexdraw.command;

import io.github.interacto.jfx.test.CommandTest;
import io.github.interacto.jfx.ui.JfxUI;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Label;
import javafx.scene.control.ProgressBar;
import javafx.scene.control.TextInputDialog;
import javafx.scene.layout.Pane;
import net.sf.latexdraw.LatexdrawExtension;
import net.sf.latexdraw.util.SystemUtils;
import net.sf.latexdraw.view.svg.SVGDocumentGenerator;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.jupiter.api.io.TempDir;
import org.mockito.Mockito;
import org.testfx.framework.junit5.ApplicationExtension;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.fail;

/**
 * Test class for the command ExportTemplate. Generated by Interacto test-gen.
 */
@Tag("command")
@ExtendWith(LatexdrawExtension.class)
@ExtendWith(ApplicationExtension.class)
class ExportTemplateTest extends CommandTest<ExportTemplate> {
	SVGDocumentGenerator svgGen;
	Pane templatesPane;
	ProgressBar progressBar;
	Label statusWidget;
	JfxUI ui;
	Alert alertName;
	TextInputDialog inputName;
	@TempDir Path dir;
	SystemUtils formerUtils;

	@BeforeEach
	void setUp() {
		formerUtils = SystemUtils.getInstance();
	}

	@AfterEach
	void tearDown() {
		SystemUtils.setSingleton(formerUtils);
	}

	@Override
	protected Stream<Runnable> canDoFixtures() {
		return Stream.of(
			() -> Mockito.when(inputName.showAndWait()).thenReturn(Optional.empty()),
			() -> Mockito.when(inputName.showAndWait()).thenReturn(Optional.of("foobarrrrrr")),
			() -> {
			final Path path = dir.resolve("foo.svg");
			try {
				Files.write(path, List.of("foo"));
				Mockito.when(inputName.showAndWait()).thenReturn(Optional.of(path.toFile().toString().replaceAll(".svg", "")));
				Mockito.when(alertName.showAndWait()).thenReturn(Optional.of(ButtonType.NO));
			}catch(final IOException ex) {
				fail(ex.getMessage());
			}
		}, () -> {
			final Path path = dir.resolve("bar.svg");
			try {
				Files.write(path, List.of("foo"));
				Mockito.when(inputName.showAndWait()).thenReturn(Optional.of(path.toFile().toString().replaceAll(".svg", "")));
				Mockito.when(alertName.showAndWait()).thenReturn(Optional.of(ButtonType.OK));
			}catch(final IOException ex) {
				fail(ex.getMessage());
			}
		});
	}

	@Override
	protected void commonCanDoFixture() {
		final SystemUtils utils = Mockito.mock(SystemUtils.class);
		Mockito.when(utils.getPathTemplatesDirUser()).thenReturn("");
		SystemUtils.setSingleton(utils);
		svgGen = Mockito.mock(SVGDocumentGenerator.class);
		ui = Mockito.mock(JfxUI.class);
		statusWidget = Mockito.mock(Label.class);
		progressBar = Mockito.mock(ProgressBar.class);
		templatesPane = Mockito.mock(Pane.class);
		alertName = Mockito.mock(Alert.class);
		inputName = Mockito.mock(TextInputDialog.class);
		cmd = new ExportTemplate(templatesPane, svgGen, ui, progressBar, statusWidget, alertName, inputName);
	}

	@Override
	protected Stream<Runnable> doCheckers() {
		return Stream.of(() -> {
			assertThat(cmd.hadEffect()).isFalse();
			Mockito.verify(svgGen, Mockito.never()).saveTemplate(Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any());
		}, () -> {
			assertThat(cmd.hadEffect()).isTrue();
			Mockito.verify(svgGen, Mockito.times(1)).saveTemplate(Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any());
		}, () -> {
			assertThat(cmd.hadEffect()).isFalse();
			Mockito.verify(svgGen, Mockito.never()).saveTemplate(Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any());
		}, () -> {
			assertThat(cmd.hadEffect()).isTrue();
			Mockito.verify(svgGen, Mockito.times(1)).saveTemplate(Mockito.anyString(), Mockito.any(), Mockito.any(), Mockito.any());
		});
	}
}
