/* © SRSoftware 2025 */
package de.srsoftware.umbrella.core;

import static de.srsoftware.tools.Optionals.nullable;
import static java.lang.System.Logger.Level.*;
import static java.net.HttpURLConnection.*;

import com.sun.net.httpserver.HttpExchange;
import de.srsoftware.tools.Path;
import de.srsoftware.tools.PathHandler;
import de.srsoftware.umbrella.core.api.*;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;

public abstract class BaseHandler extends PathHandler {

	public record Page(String mime, byte[] bytes){}


	public HttpExchange addCors(HttpExchange ex){
		var headers = ex.getRequestHeaders();
		var origin = nullable(headers.get("Origin")).orElse(List.of()).stream().filter(url -> url.contains("://localhost")||url.contains("://127.0.0.1")).findAny();
		if (origin.isPresent()) {
			var url = origin.get();
			headers = ex.getResponseHeaders();
			headers.add("Allow-Origin", url);
			headers.add("Access-Control-Allow-Origin", url);
			headers.add("Access-Control-Allow-Headers", "Content-Type");
			headers.add("Access-Control-Allow-Credentials", "true");
			headers.add("Access-Control-Allow-Methods","DELETE, GET, POST, PATCH");
			headers.add("Access-Control-Expose-Headers","Content-Disposition");
		}
		return ex;
	}

	@Override
	public boolean doOptions(Path path, HttpExchange ex) throws IOException {
		return ok(addCors(ex));
	}

	public boolean load(Path path, HttpExchange ex) throws IOException {
		try {
			var doc = load(path.toString());
			ex.getResponseHeaders().add(CONTENT_TYPE, doc.mime);
			return sendContent(ex,doc.bytes);
		} catch (UmbrellaException e) {
			throw new RuntimeException(e);
		}
	}

	public Page load(String resourcePath) throws IOException, UmbrellaException {
		var url = getClass().getClassLoader().getResource(resourcePath);
		if (url == null) throw new UmbrellaException(HTTP_NOT_FOUND,"{0} not found!",resourcePath);
		LOG.log(DEBUG,"Trying to load {0}",url);
		var bos = new ByteArrayOutputStream();
		var conn = url.openConnection();
		var mime = conn.getContentType();
		try (var stream = conn.getInputStream()){
			stream.transferTo(bos);
			return new Page(mime,bos.toByteArray());
		} catch (Exception e) {
			LOG.log(WARNING,"Failed to load {0}",url);
			throw new UmbrellaException(HTTP_NOT_FOUND,"Failed to load {0}",url);
		}
	}

	public boolean ok(HttpExchange ex) throws IOException {
		return sendEmptyResponse(HTTP_OK,ex);
	}

	public boolean send(HttpExchange ex, UmbrellaException e) throws IOException {
		var cause = e.getCause();
		String lang = languages(ex).stream().findFirst().orElse("en");
		var translatedMessage = e.message().translate(lang);
		if (cause != null) LOG.log(ERROR,translatedMessage,cause);
		return sendContent(ex,e.statusCode(),translatedMessage);
	}

	public boolean unauthorized(HttpExchange ex) throws IOException {
		return sendEmptyResponse(HTTP_UNAUTHORIZED,ex);
	}
}
