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

import static de.srsoftware.umbrella.core.Util.mapLogLevel;
import static de.srsoftware.umbrella.core.constants.Constants.UMBRELLA;
import static java.lang.System.Logger.Level.ERROR;
import static java.lang.System.Logger.Level.INFO;

import com.sun.net.httpserver.HttpServer;
import de.srsoftware.configuration.JsonConfig;
import de.srsoftware.tools.ColorLogger;
import de.srsoftware.umbrella.accounting.AccountingModule;
import de.srsoftware.umbrella.bookmarks.BookmarkApi;
import de.srsoftware.umbrella.company.CompanyModule;
import de.srsoftware.umbrella.contact.ContactModule;
import de.srsoftware.umbrella.core.SettingsService;
import de.srsoftware.umbrella.core.exceptions.UmbrellaException;
import de.srsoftware.umbrella.documents.DocumentApi;
import de.srsoftware.umbrella.files.FileModule;
import de.srsoftware.umbrella.journal.JournalModule;
import de.srsoftware.umbrella.legacy.*;
import de.srsoftware.umbrella.markdown.MarkdownApi;
import de.srsoftware.umbrella.message.MessageSystem;
import de.srsoftware.umbrella.messagebus.MessageApi;
import de.srsoftware.umbrella.notes.NoteModule;
import de.srsoftware.umbrella.poll.PollModule;
import de.srsoftware.umbrella.project.ProjectModule;
import de.srsoftware.umbrella.stock.StockModule;
import de.srsoftware.umbrella.tags.TagModule;
import de.srsoftware.umbrella.task.TaskModule;
import de.srsoftware.umbrella.time.TimeModule;
import de.srsoftware.umbrella.translations.Translations;
import de.srsoftware.umbrella.user.UserModule;
import de.srsoftware.umbrella.web.WebHandler;
import de.srsoftware.umbrella.wiki.WikiModule;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import org.json.JSONObject;

public class Application {
	private static final System.Logger LOG       = System.getLogger("Umbrella");

	private static JsonConfig configureLogging(JsonConfig jsonConfig) {
		var rootLevel = jsonConfig.get("umbrella.logging.rootLevel", "INFO");
		ColorLogger.setRootLogLevel(mapLogLevel(rootLevel));

		var loggers = jsonConfig.get("umbrella.logging.loggers").orElse(null);
		if (loggers instanceof JSONObject json){
			json.keySet().forEach(key -> {
				var lvl = mapLogLevel(json.getString(key));
				ColorLogger.setLogLevel(key,lvl);
			});
		}
		return jsonConfig;
	}

	public static void main(String[] args) throws IOException, UmbrellaException {
		LOG.log(INFO, "Starting Umbrella:");
		var config            = configureLogging(new JsonConfig(UMBRELLA));
		var	port              = config.get("umbrella.http.port", 8080);
		var	threads           = config.get("umbrella.threads", 16);

		var server            = HttpServer.create(new InetSocketAddress(port), 0);
		try {
			new Translations(config).bindPath("/api/translations").on(server);
			new JournalModule(config).bindPath("/api/journal").on(server);
			new MessageApi().bindPath("/api/bus").on(server);
			new MessageSystem(config).bindPath("/api/message").on(server);
			new UserModule(config).bindPath("/api/user").on(server);
			new TagModule(config).bindPath("/api/tags").on(server);
			new BookmarkApi(config).bindPath("/api/bookmark").on(server);
			new CompanyModule(config).bindPath("/api/company").on(server);
			new CompanyLegacy(config).bindPath("/legacy/company").on(server);
			new ContactModule(config).bindPath("/api/contact").on(server);
			new DocumentApi(config).bindPath("/api/document").on(server);
			new UserLegacy(config).bindPath("/legacy/user").on(server);
			new NotesLegacy(config).bindPath("/legacy/notes").on(server);
			new MarkdownApi(config).bindPath("/api/markdown").on(server);
			new NoteModule(config).bindPath("/api/notes").on(server);
			new StockModule(config).bindPath("/api/stock").on(server);
			new PollModule(config).bindPath("/api/poll").on(server);
			new ProjectModule(config).bindPath("/api/project").on(server);
			new ProjectLegacy(config).bindPath("/legacy/project").on(server);
			new TaskModule(config).bindPath("/api/task").on(server);
			new TaskLegacy().bindPath("/legacy/task").on(server);
			new TimeModule(config).bindPath("/api/time").on(server);
			new WebHandler().bindPath("/").on(server);
			new WikiModule(config).bindPath("/api/wiki").on(server);
			new FileModule(config).bindPath("/api/files").on(server);
			new SettingsService(config).bindPath("/api/settings").on(server);
			new AccountingModule(config).bindPath("/api/accounting").on(server);
		} catch (Exception e) {
			LOG.log(ERROR,"Startup failed",e);
			System.exit(-1);
		}
		server.setExecutor(Executors.newFixedThreadPool(threads));
		server.start();
		LOG.log(INFO,"Started web server at port {0}",port);
	}
}
