package cz.hsrs.rest.provider;

import java.sql.SQLException;
import java.util.List;

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

import org.mortbay.jetty.HttpStatus;

import cz.hsrs.rest.ParamsList;
import cz.hsrs.rest.beans.ExceptionBean;
import cz.hsrs.rest.beans.LastObsTimestampBean;
import cz.hsrs.rest.beans.UserBean;
import cz.hsrs.rest.util.AuthUtil;
import cz.hsrs.rest.util.ObservationRestUtil;
import cz.hsrs.rest.util.UserRestUtil;
import cz.hsrs.servlet.security.LoginUser;

/**
 * Special servlet for services used by monitoring applications
 * 
 * @author mkepka
 *
 */
@Path("/watchdog")
public class WatchDogRest {

	/**
	 * Empty constructor
	 */
	public WatchDogRest() {
	}

	/**
	 * Test service for validating DB connection. It returns user details for logged user.
	 * @param req
	 * @return
	 */
	@Path("/test")
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public Response testDB(@Context HttpServletRequest req) {
		try {
            LoginUser loggedUser = AuthUtil.getAuthenticatedLoginUser(req);
            UserBean userDetails = UserRestUtil.getUser(loggedUser.getUserName());
            return Response.ok().entity(userDetails)
                    .build();
        } catch (AuthenticationException e1) {
            return Response.status(HttpStatus.ORDINAL_401_Unauthorized)
                    .entity(new ExceptionBean(e1.getClass().getName(), "Authentication failure for request!"))
                    .build();
        } catch (SQLException e) {
            return Response.status(HttpStatus.ORDINAL_500_Internal_Server_Error)
                    .entity(new ExceptionBean(e.getClass().getName(), e.getLocalizedMessage()))
                    .build();
        }
	}
	/**
	 * Service provides list of observation last time stamps for given group
	 * e.g. /rest/watchdog/group?group_name=kynsperk 
	 * e.g. /rest/watchdog/group?group_id=8
	 * @param groupId - ID of group
	 * @param groupName - name of group
	 * @param req HTTPRequest contains logged user session
	 * @return List of observations timestamps
	 */
	@Path("/group/")
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public Response getLastTimestampsPerGroup(@QueryParam(ParamsList.GROUP_ID) Integer groupId,
											  @QueryParam(ParamsList.GROUP_NAME) String groupName,
											  @Context HttpServletRequest req) {
		try {
			LoginUser loggedUser = AuthUtil.getAuthenticatedLoginUser(req);
			
			/* to check last values needs to have superuser rights */
			if(loggedUser.getRightsId() < 0) {
				List<LastObsTimestampBean> obsList = ObservationRestUtil.getLastTimestampPerGroup(groupName, groupId);
				return Response.ok().entity(obsList)
	                    .build();
			}
			else {
				throw new AuthenticationException();
			}
		} catch (AuthenticationException e1) {
            return Response.status(HttpStatus.ORDINAL_401_Unauthorized)
                    .entity(new ExceptionBean(e1.getClass().getName(), "Authentication failure for request!"))
                    .build();
		} catch (SQLException e) {
            return Response.status(HttpStatus.ORDINAL_500_Internal_Server_Error)
                    .entity(new ExceptionBean(e.getClass().getName(), e.getLocalizedMessage()))
                    .build();
        }
	}
	
	/**
	 * Service provides list of observation last time stamps for given unit or list of units
	 * e.g.: /rest/watchdog/unit?unit_id=1305167549144045 
	 * e.g.: /rest/watchdog/unit?unit_id=1305167549144045,1305167549149707
	 * @param unitId
	 * @param req
	 * @return
	 */
	@Path("/unit/")
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public Response getLastTimestampsPerUnit(@QueryParam(ParamsList.UNIT_ID) String unitId,
										     @Context HttpServletRequest req) {
		try {
			LoginUser loggedUser = AuthUtil.getAuthenticatedLoginUser(req);
			
			/* to check last values needs to have superuser rights */
			if(loggedUser.getRightsId() < 0) {
				List<LastObsTimestampBean> obsList = ObservationRestUtil.getLastTimestampPerUnit(unitId);
				return Response.ok().entity(obsList)
	                    .build();
			}
			else {
				throw new AuthenticationException();
			}
		} catch (AuthenticationException e1) {
            return Response.status(HttpStatus.ORDINAL_401_Unauthorized)
                    .entity(new ExceptionBean(e1.getClass().getName(), "Authentication failure for request!"))
                    .build();
		} catch (SQLException e) {
            return Response.status(HttpStatus.ORDINAL_500_Internal_Server_Error)
                    .entity(new ExceptionBean(e.getClass().getName(), e.getLocalizedMessage()))
                    .build();
        }
	}
	
	/**
	 * Service provides list of observation last time stamps for given sensor or list of sensors
	 * e.g.: /rest/watchdog/sensor?sensor_id=560030000
	 * e.g.: /rest/watchdog/sensor?sensor_id=560030000,360200000
	 * @param sensorId
	 * @param req
	 * @return
	 */
	@Path("/sensor/")
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public Response getLastTimestampsPerSensor(@QueryParam(ParamsList.SENSOR_ID) String sensorId,
										     @Context HttpServletRequest req) {
		try {
			LoginUser loggedUser = AuthUtil.getAuthenticatedLoginUser(req);
			
			/* to check last values needs to have superuser rights */
			if(loggedUser.getRightsId() < 0) {
				List<LastObsTimestampBean> obsList = ObservationRestUtil.getLastTimestampPerSensor(sensorId);
				return Response.ok().entity(obsList)
	                    .build();
			}
			else {
				throw new AuthenticationException();
			}
		} catch (AuthenticationException e1) {
            return Response.status(HttpStatus.ORDINAL_401_Unauthorized)
                    .entity(new ExceptionBean(e1.getClass().getName(), "Authentication failure for request!"))
                    .build();
		} catch (SQLException e) {
            return Response.status(HttpStatus.ORDINAL_500_Internal_Server_Error)
                    .entity(new ExceptionBean(e.getClass().getName(), e.getLocalizedMessage()))
                    .build();
        }
	}
}