/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

 package org.apache.ranger.rest;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;

import org.apache.log4j.Logger;
import org.apache.ranger.biz.UserMgr;
import org.apache.ranger.biz.XUserMgr;
import org.apache.ranger.common.MessageEnums;
import org.apache.ranger.common.RESTErrorUtil;
import org.apache.ranger.common.RangerConfigUtil;
import org.apache.ranger.common.RangerConstants;
import org.apache.ranger.common.SearchCriteria;
import org.apache.ranger.common.SearchUtil;
import org.apache.ranger.common.StringUtil;
import org.apache.ranger.common.annotation.RangerAnnotationClassName;
import org.apache.ranger.common.annotation.RangerAnnotationJSMgrName;
import org.apache.ranger.common.annotation.RangerAnnotationRestAPI;
import org.apache.ranger.db.RangerDaoManager;
import org.apache.ranger.entity.XXPortalUser;
import org.apache.ranger.security.context.RangerAPIList;
import org.apache.ranger.util.RangerRestUtil;
import org.apache.ranger.view.VXPasswordChange;
import org.apache.ranger.view.VXPortalUser;
import org.apache.ranger.view.VXPortalUserList;
import org.apache.ranger.view.VXResponse;
import org.apache.ranger.view.VXStringList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;


@Path("users")
@Component
@Scope("request")
@RangerAnnotationJSMgrName("UserMgr")
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class UserREST {
	private static final Logger logger = Logger.getLogger(UserREST.class);

	@Autowired
	StringUtil stringUtil;

	@Autowired
	RangerDaoManager daoManager;

	@Autowired
	RangerConfigUtil configUtil;

	@Autowired
	RESTErrorUtil restErrorUtil;

	@Autowired
	SearchUtil searchUtil;

	@Autowired
	UserMgr userManager;

	@Autowired
	RangerRestUtil msRestUtil;
	
	@Autowired
	XUserMgr xUserMgr;

	/**
	 * Implements the traditional search functionalities for UserProfile
	 *
	 * @param request
	 * @return
	 */
	@GET
	@Produces({ "application/xml", "application/json" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.SEARCH_USERS + "\")")
	public VXPortalUserList searchUsers(@Context HttpServletRequest request) {
		String[] approvedSortByParams = new String[] { "requestDate",
				"approvedDate", "activationDate", "emailAddress", "firstName",
				"lastName" };
		@SuppressWarnings("deprecation")
		SearchCriteria searchCriteria = searchUtil.extractCommonCriterias(
				request, approvedSortByParams);

		// userId
		searchUtil.extractLong(request, searchCriteria, "userId", "User Id");

		// loginId
		searchUtil.extractString(request, searchCriteria, "loginId",
				"Login Id", null);

		// emailAddress
		searchUtil.extractString(request, searchCriteria, "emailAddress",
				"Email Address", null);

		// firstName
		searchUtil.extractString(request, searchCriteria, "firstName",
				"First Name", StringUtil.VALIDATION_NAME);

		// lastName
		searchUtil.extractString(request, searchCriteria, "lastName",
				"Last Name", StringUtil.VALIDATION_NAME);

		// status
		searchUtil.extractEnum(request, searchCriteria, "status", "Status",
				"statusList", RangerConstants.ActivationStatus_MAX);

		// publicScreenName
		searchUtil.extractString(request, searchCriteria, "publicScreenName",
				"Public Screen Name", StringUtil.VALIDATION_NAME);
		// roles
		searchUtil.extractStringList(request, searchCriteria, "role", "Role",
				"roleList", configUtil.getRoles(), StringUtil.VALIDATION_NAME);

		return userManager.searchUsers(searchCriteria);
	}

	/**
	 * Return the VUserProfile for the given userId
	 *
	 * @param userId
	 * @return
	 */
	@GET
	@Path("{userId}")
	@Produces({ "application/xml", "application/json" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.GET_USER_PROFILE_FOR_USER + "\")")
	public VXPortalUser getUserProfileForUser(@PathParam("userId") Long userId) {
		try {
			VXPortalUser userProfile = userManager.getUserProfile(userId);
			if (userProfile != null) {
				if (logger.isDebugEnabled()) {
					logger.debug("getUserProfile() Found User userId=" + userId);
				}
			} else {
				logger.debug("getUserProfile() Not found userId=" + userId);
			}
			return userProfile;
		} catch (Throwable t) {
			logger.error("getUserProfile() no user session. error="
					+ t.toString());
		}
		return null;
	}

	@POST
	@Consumes({ "application/json", "application/xml" })
	@Produces({ "application/xml", "application/json" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.CREATE + "\")")
	public VXPortalUser create(VXPortalUser userProfile,
			@Context HttpServletRequest servletRequest) {
		logger.info("create:" + userProfile.getEmailAddress());

		return userManager.createUser(userProfile);
	}
	
	// API to add user with default account
	@POST
	@Path("/default")
	@Consumes({ "application/json", "application/xml" })
	@Produces({ "application/xml", "application/json" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.CREATE_DEFAULT_ACCOUNT_USER + "\")")
	public VXPortalUser createDefaultAccountUser(VXPortalUser userProfile,
			@Context HttpServletRequest servletRequest) {
		VXPortalUser vxPortalUser;
		vxPortalUser=userManager.createDefaultAccountUser(userProfile);
		if(vxPortalUser!=null)
		{
			xUserMgr.assignPermissionToUser(vxPortalUser, true);
		}
		 return vxPortalUser;
	}


	@PUT
	@Consumes({ "application/json", "application/xml" })
	@Produces({ "application/xml", "application/json" })
	@RangerAnnotationRestAPI(updates_classes = "VUserProfile")
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.UPDATE + "\")")
	public VXPortalUser update(VXPortalUser userProfile,
			@Context HttpServletRequest servletRequest) {
		logger.info("update:" + userProfile.getEmailAddress());
		XXPortalUser gjUser = daoManager.getXXPortalUser().getById(userProfile.getId());
		userManager.checkAccess(gjUser);
		if (gjUser != null) {
			msRestUtil.validateVUserProfileForUpdate(gjUser, userProfile);
			gjUser = userManager.updateUser(userProfile);
			return userManager.mapXXPortalUserVXPortalUser(gjUser);
		} else {
			logger.info("update(): Invalid userId provided: userId="
					+ userProfile.getId());
			throw restErrorUtil.createRESTException("serverMsg.userRestUser",
					MessageEnums.DATA_NOT_FOUND, null, null,
					userProfile.toString());
		}
	}

	@PUT
	@Path("/{userId}/roles")
	@Produces({ "application/xml", "application/json" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.SET_USER_ROLES + "\")")
	public VXResponse setUserRoles(@PathParam("userId") Long userId,
			VXStringList roleList) {
		userManager.checkAccess(userId);
		userManager.setUserRoles(userId, roleList.getVXStrings());
		VXResponse response = new VXResponse();
		response.setStatusCode(VXResponse.STATUS_SUCCESS);
		return response;
	}

	/**
	 * Deactivate the user
	 *
	 * @param userId
	 * @return
	 */
	@POST
	@Path("{userId}/deactivate")
	@Produces({ "application/xml", "application/json" })
	@PreAuthorize("@rangerPreAuthSecurityHandler.isAPIAccessible(\"" + RangerAPIList.DEACTIVATE_USER + "\")")
	@RangerAnnotationClassName(class_name = VXPortalUser.class)
	public VXPortalUser deactivateUser(@PathParam("userId") Long userId) {
		XXPortalUser gjUser = daoManager.getXXPortalUser().getById(userId);
		if (gjUser == null) {
			logger.info("update(): Invalid userId provided: userId=" + userId);
			throw restErrorUtil.createRESTException("serverMsg.userRestUser",
					MessageEnums.DATA_NOT_FOUND, null, null, "" + userId);
		}
		return userManager.deactivateUser(gjUser);
	}

	/**
	 * This method returns the VUserProfile for the current session
	 *
	 * @param request
	 * @return
	 */
	@GET
	@Path("/profile")
	@Produces({ "application/xml", "application/json" })
	public VXPortalUser getUserProfile(@Context HttpServletRequest request) {
		try {
			logger.debug("getUserProfile(). httpSessionId="
					+ request.getSession().getId());
			VXPortalUser userProfile = userManager.getUserProfileByLoginId();
			return userProfile;
		} catch (Throwable t) {
			logger.error(
					"getUserProfile() no user session. error=" + t.toString(),
					t);
		}
		return null;
	}

	@GET
	@Path("/firstnames")
	@Produces({ "application/xml", "application/json" })
	public String suggestUserFirstName(@QueryParam("letters") String letters,
			@Context HttpServletRequest req) {
		return null;
	}

	/**	
	 * @param userId
	 * @param changePassword
	 * @return
	 */
	@POST
	@Path("{userId}/passwordchange")
	@Produces({ "application/xml", "application/json" })
	public VXResponse changePassword(@PathParam("userId") Long userId,
			VXPasswordChange changePassword) {
		if(changePassword==null || stringUtil.isEmpty(changePassword.getLoginId())){
			logger.warn("SECURITY:changePassword(): Invalid loginId provided. loginId was empty or null");
			throw restErrorUtil.createRESTException("serverMsg.userRestUser",MessageEnums.DATA_NOT_FOUND, null, null,"");
		}

		logger.info("changePassword:" + changePassword.getLoginId());
		XXPortalUser gjUser = daoManager.getXXPortalUser().findByLoginId(changePassword.getLoginId());
		if (gjUser == null) {
			logger.warn("SECURITY:changePassword(): Invalid loginId provided: loginId="+ changePassword.getLoginId());
			throw restErrorUtil.createRESTException("serverMsg.userRestUser",MessageEnums.DATA_NOT_FOUND, null, null, changePassword.getLoginId());
		}

		userManager.checkAccessForUpdate(gjUser);
		changePassword.setId(gjUser.getId());
 		VXResponse ret = userManager.changePassword(changePassword);
		return ret;
	}

	/**	
	 *
	 * @param userId
	 * @param changeEmail
	 * @return
	 */
	@POST
	@Path("{userId}/emailchange")
	@Produces({ "application/xml", "application/json" })
	public VXPortalUser changeEmailAddress(@PathParam("userId") Long userId,
			VXPasswordChange changeEmail) {
		if(changeEmail==null || stringUtil.isEmpty(changeEmail.getLoginId())){
			logger.warn("SECURITY:changeEmail(): Invalid loginId provided. loginId was empty or null");
			throw restErrorUtil.createRESTException("serverMsg.userRestUser",MessageEnums.DATA_NOT_FOUND, null, null,"");
		}

		logger.info("changeEmail:" + changeEmail.getLoginId());
		XXPortalUser gjUser = daoManager.getXXPortalUser().findByLoginId(changeEmail.getLoginId());
		if (gjUser == null) {
			logger.warn("SECURITY:changeEmail(): Invalid loginId provided: loginId="+ changeEmail.getLoginId());
			throw restErrorUtil.createRESTException("serverMsg.userRestUser",MessageEnums.DATA_NOT_FOUND, null, null, changeEmail.getLoginId());
		}

		userManager.checkAccessForUpdate(gjUser);
		changeEmail.setId(gjUser.getId());
		VXPortalUser ret = userManager.changeEmailAddress(gjUser, changeEmail);
		return ret;
	}

}