package library.routes;

import java.util.Optional;

import io.javalin.http.Context;
import io.javalin.http.Handler;
import io.javalin.http.HandlerType;
import io.javalin.http.UnauthorizedResponse;
import library.domain.Member;
import library.service.SessionService;

/**
 * Runs before every request: who is this?
 *
 * Missing, unknown, or expired token → 401, and no route runs. Otherwise the
 * member goes on the context for the routes to read. This only answers "who?";
 * roles and ownership are checked later.
 */
public class AuthFilter implements Handler {

	private final SessionService sessions;

	public AuthFilter(SessionService sessions) {
		this.sessions = sessions;
	}

	@Override
	public void handle(Context ctx) throws Exception {
		if (isPublic(ctx)) {
			return;
		}
		Optional<String> token = Auth.bearerToken(ctx);
		if (token.isEmpty()) {
			throw new UnauthorizedResponse();
		}
		Optional<Member> member = sessions.memberForToken(token.get());
		if (member.isEmpty()) {
			throw new UnauthorizedResponse(); // unknown or expired token
		}
		ctx.attribute(Auth.MEMBER, member.get());
	}

	// The short list of requests that don't need a token.
	// Everything else is locked by default.
	private boolean isPublic(Context ctx) {
		String path = ctx.path();
		if (ctx.method().equals(HandlerType.POST)) {
			return path.equals("/login") || path.equals("/members"); // log in, register
		}
		if (ctx.method().equals(HandlerType.GET)) {
			return path.equals("/") || path.equals("/index.html"); // the browser front end
		}
		return false;
	}
}
