package myServerTests.myServlets;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import org.eclipse.jetty.server.Request;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;

import io.vavr.control.Try;
import jakarta.servlet.MultipartConfigElement;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.Part;
import myServerTests.myServer.MyContext;

public class MyUploadServlet extends HttpServlet {

	public static String getForm() {

		final Document document = Document.createShell("");

		document.outputSettings().prettyPrint(true);

		{

			final String actionValue = String.format("/%s/%s", MyContext.ServletContextHandler.value,
					MyContext.MyUploadServlet.value);

			final Element form = document.body().appendElement("form").attr("method", "post")
					.attr("action", actionValue).attr("enctype", "multipart/form-data");

			form.appendElement("input").attr("type", "file").attr("name", "myUploadFile").attr("required", "");

			form.appendElement("input").attr("type", "submit").attr("value", "Upload selected file");

		}

		return document.toString();

	}

	private static String getResponse(final List<String> strings) {

		final Document document = Document.createShell("");

		document.outputSettings().prettyPrint(true);

		final Element elementUL = document.createElement("UL");
		document.body().appendChild(elementUL);

		strings.forEach(string -> {

			elementUL.appendChild(document.createElement("LI").appendText(string));

		});

		return document.toString();

	}

	@Override
	protected void doGet(final HttpServletRequest httpServletRequest, final HttpServletResponse httpServletResponse)
			throws ServletException, IOException {

		httpServletResponse.setContentType("text/html; charset=utf-8");

		httpServletResponse.setStatus(HttpServletResponse.SC_OK);

		httpServletResponse.getWriter().println(MyUploadServlet.getForm());

	}

	@Override
	protected void doPost(final HttpServletRequest httpServletRequest, final HttpServletResponse httpServletResponse)
			throws ServletException, IOException {

		if (Objects.nonNull(httpServletRequest.getContentType())) {

			final String contentType = httpServletRequest.getContentType();

			if (contentType.startsWith("multipart/form-data")) {

				final MultipartConfigElement multipartConfigElement = new MultipartConfigElement(
						System.getProperty("java.io.tmpdir"));

				httpServletRequest.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, multipartConfigElement);

			}

		}

		final Path createDirectory = Files.createDirectories(Path.of("myUpLoadFolder"));

		final Path myUpLoadFolder = createDirectory.toAbsolutePath();

		final List<String> strings = new ArrayList<>();

		final List<Part> parts = httpServletRequest.getParts().stream().filter(part -> part.getSize() > 0)
				.collect(Collectors.toList());

		if (parts.isEmpty()) {
			strings.add("Missing file name.");
		}

		parts.forEach(part -> {

			Try.run(() -> {

				final String fileName = part.getSubmittedFileName();

				final Path resolve = myUpLoadFolder.resolve(fileName);

				Files.deleteIfExists(resolve);

				part.write(resolve.toString());

				strings.add(MessageFormat.format("{0} uploaded to {1}.", fileName, myUpLoadFolder));

			});

		});

		{

			httpServletResponse.setStatus(HttpServletResponse.SC_OK);

			httpServletResponse.setContentType("text/html; charset=utf-8");

			httpServletResponse.getWriter().println(MyUploadServlet.getResponse(strings));

		}

	}

}
