package es.uvigo.esei.daa.rest;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import es.uvigo.esei.daa.controller.UsersController;

/**
 * REST resource for managing users.
 * 
 * @author Miguel Reboiro Jato.
 */
@Path("/users")
@Produces(MediaType.APPLICATION_JSON)
public class UsersResource {

	private final UsersController controller;

	// The HttpServletRequest can be also injected as a parameter in the REST
	// methods.
	private @Context HttpServletRequest request;

	/**
	 * Constructs a new instance of {@link UsersResource}.
	 */
	public UsersResource() {
		this(new UsersController());
	}

	// Needed for testing purposes
	UsersResource(UsersController controller) {
		this(controller, null);
	}

	// Needed for testing purposes
	UsersResource(UsersController controller, HttpServletRequest request) {
		this.controller = controller;
		this.request = request;
	}

	/**
	 * Returns a user with the provided login.
	 * 
	 * @param login
	 *            the identifier of the user to retrieve.
	 * @return a 200 OK response with an user that has the provided login. If
	 *         the request is done without providing the login credentials or
	 *         using invalid credentials a 401 Unauthorized response will be
	 *         returned. If the credentials are provided and a regular user
	 *         (i.e. non admin user) tries to access the data of other user, a
	 *         403 Forbidden response will be returned. If the credentials are
	 *         OK, but the login does not corresponds with any user, a 400 Bad
	 *         Request response with an error message will be returned. If an
	 *         error happens while retrieving the list, a 500 Internal Server
	 *         Error response with an error message will be returned.
	 */
	@GET
	@Path("/{login}")
	public Response get(@PathParam("login") String login) {
		final String loggedUser = getLogin();

		// Each user can only access his or her own data. Only the admin user
		// can access the data of any user.
		if (loggedUser.equals(login) || loggedUser.equals("admin")) {
			try {
				return Response.ok(controller.get(login)).build();

			} catch (IllegalArgumentException iae) {

				return Response.status(Response.Status.BAD_REQUEST).entity(iae.getMessage()).build();

			} catch (RuntimeException e) {

				return Response.serverError().entity(e.getMessage()).build();
			}
		} else {

			return Response.status(Response.Status.UNAUTHORIZED).build();
		}
	}

	private String getLogin() {
		return (String) request.getSession().getAttribute("login");
	}
}
