package library;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import io.javalin.Javalin;
import io.javalin.http.staticfiles.Location;
import io.javalin.json.JavalinJackson;
import library.dao.BookDao;
import library.routes.BookRoutes;
import library.routes.ErrorHandler;
import library.service.BookService;

/**
 * Starts the library API on port 7000.
 *
 * The only class that knows every layer: it builds them bottom-up and hands
 * each one the layer below.
 */
public class Main {

	public static void main(String[] args) {
		BookDao bookDao = new BookDao();
		BookService bookService = new BookService(bookDao);
		BookRoutes bookRoutes = new BookRoutes(bookService);

		// Javalin 7: all configuration and routes go inside the config block
		Javalin.create(config -> {
			config.jetty.port = 7000;

			// JSON: dates as "1979-10-12" rather than [1979,10,12],
			// and ignore JSON fields a DTO doesn't have (e.g. a client-sent "bookId")
			config.jsonMapper(new JavalinJackson().updateMapper(mapper -> {
				mapper.registerModule(new JavaTimeModule());
				mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
				mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
			}));

			// A small browser front end: src/main/resources/public/index.html,
			// served at http://localhost:7000/
			config.staticFiles.add("/public", Location.CLASSPATH);

			// One place turns every exception into a status code and error JSON
			ErrorHandler.register(config);

			bookRoutes.register(config);
		}).start();
	}
}
