/**
   * POST /users : Creates a new user.
   *
   * <p>Creates a new user if the login and email are not already used, and sends an mail with an
   * activation link. The user needs to be activated on creation.
   *
   * @param managedUserVM the user to create
   * @return the ResponseEntity with status 201 (Created) and with body the new user, or with status
   *     400 (Bad Request) if the login or email is already in use
   * @throws URISyntaxException if the Location URI syntax is incorrect
   */
  @PostMapping("/users")
  @Timed
  @Secured(AuthoritiesConstants.ADMIN)
  public ResponseEntity<?> createUser(@RequestBody ManagedUserVM managedUserVM)
      throws URISyntaxException {
    log.debug("REST request to save User : {}", managedUserVM);

    // Lowercase the user login before comparing with database
    if (userRepository.findOneByLogin(managedUserVM.getLogin().toLowerCase()).isPresent()) {
      return ResponseEntity.badRequest()
          .headers(
              HeaderUtil.createFailureAlert("userManagement", "userexists", "Login already in use"))
          .body(null);
    } else if (userRepository.findOneByEmail(managedUserVM.getEmail()).isPresent()) {
      return ResponseEntity.badRequest()
          .headers(
              HeaderUtil.createFailureAlert(
                  "userManagement", "emailexists", "Email already in use"))
          .body(null);
    } else {
      User newUser = userService.createUser(managedUserVM);
      mailService.sendCreationEmail(newUser);
      return ResponseEntity.created(new URI("/api/users/" + newUser.getLogin()))
          .headers(HeaderUtil.createAlert("userManagement.created", newUser.getLogin()))
          .body(newUser);
    }
  }
  /**
   * PUT /users : Updates an existing User.
   *
   * @param managedUserVM the user to update
   * @return the ResponseEntity with status 200 (OK) and with body the updated user, or with status
   *     400 (Bad Request) if the login or email is already in use, or with status 500 (Internal
   *     Server Error) if the user couldn't be updated
   */
  @PutMapping("/users")
  @Timed
  @Secured(AuthoritiesConstants.ADMIN)
  public ResponseEntity<ManagedUserVM> updateUser(@RequestBody ManagedUserVM managedUserVM) {
    log.debug("REST request to update User : {}", managedUserVM);
    Optional<User> existingUser = userRepository.findOneByEmail(managedUserVM.getEmail());
    if (existingUser.isPresent() && (!existingUser.get().getId().equals(managedUserVM.getId()))) {
      return ResponseEntity.badRequest()
          .headers(
              HeaderUtil.createFailureAlert(
                  "userManagement", "emailexists", "E-mail already in use"))
          .body(null);
    }
    existingUser = userRepository.findOneByLogin(managedUserVM.getLogin().toLowerCase());
    if (existingUser.isPresent() && (!existingUser.get().getId().equals(managedUserVM.getId()))) {
      return ResponseEntity.badRequest()
          .headers(
              HeaderUtil.createFailureAlert("userManagement", "userexists", "Login already in use"))
          .body(null);
    }
    userService.updateUser(
        managedUserVM.getId(),
        managedUserVM.getLogin(),
        managedUserVM.getFirstName(),
        managedUserVM.getLastName(),
        managedUserVM.getEmail(),
        managedUserVM.isActivated(),
        managedUserVM.getLangKey(),
        managedUserVM.getAuthorities());

    return ResponseEntity.ok()
        .headers(HeaderUtil.createAlert("userManagement.updated", managedUserVM.getLogin()))
        .body(new ManagedUserVM(userService.getUserWithAuthorities(managedUserVM.getId())));
  }
 /**
  * DELETE /users/:login : delete the "login" User.
  *
  * @param login the login of the user to delete
  * @return the ResponseEntity with status 200 (OK)
  */
 @DeleteMapping("/users/{login:"******"}")
 @Timed
 @Secured(AuthoritiesConstants.ADMIN)
 public ResponseEntity<Void> deleteUser(@PathVariable String login) {
   log.debug("REST request to delete User: {}", login);
   userService.deleteUser(login);
   return ResponseEntity.ok()
       .headers(HeaderUtil.createAlert("userManagement.deleted", login))
       .build();
 }
 /**
  * DELETE USER :login : delete the "login" User.
  *
  * @param login the login of the user to delete
  * @return the ResponseEntity with status 200 (OK)
  */
 @RequestMapping(
     value = "/users/{login:"******"}",
     method = RequestMethod.DELETE,
     produces = MediaType.APPLICATION_JSON_VALUE)
 @Timed
 @Secured(AuthoritiesConstants.ADMIN)
 public ResponseEntity<Void> deleteUser(@PathVariable String login) {
   log.debug("REST request to delete User: {}", login);
   userService.deleteUserInformation(login);
   return ResponseEntity.ok()
       .headers(HeaderUtil.createAlert("userManagement.deleted", login))
       .build();
 }
 /**
  * PUT /users : Updates an existing User.
  *
  * @param managedUserDTO the user to update
  * @return the ResponseEntity with status 200 (OK) and with body the updated user, or with status
  *     400 (Bad Request) if the login or email is already in use, or with status 500 (Internal
  *     Server Error) if the user couldnt be updated
  */
 @RequestMapping(
     value = "/users",
     method = RequestMethod.PUT,
     produces = MediaType.APPLICATION_JSON_VALUE)
 @Timed
 @Transactional
 @Secured(AuthoritiesConstants.ADMIN)
 public ResponseEntity<ManagedUserDTO> updateUser(@RequestBody ManagedUserDTO managedUserDTO) {
   log.debug("REST request to update User : {}", managedUserDTO);
   Optional<User> existingUser = userRepository.findOneByEmail(managedUserDTO.getEmail());
   if (existingUser.isPresent() && (!existingUser.get().getId().equals(managedUserDTO.getId()))) {
     return ResponseEntity.badRequest()
         .headers(
             HeaderUtil.createFailureAlert(
                 "userManagement", "emailexists", "E-mail already in use"))
         .body(null);
   }
   existingUser = userRepository.findOneByLogin(managedUserDTO.getLogin().toLowerCase());
   if (existingUser.isPresent() && (!existingUser.get().getId().equals(managedUserDTO.getId()))) {
     return ResponseEntity.badRequest()
         .headers(
             HeaderUtil.createFailureAlert("userManagement", "userexists", "Login already in use"))
         .body(null);
   }
   return userRepository
       .findOneById(managedUserDTO.getId())
       .map(
           user -> {
             user.setLogin(managedUserDTO.getLogin());
             user.setFirstName(managedUserDTO.getFirstName());
             user.setLastName(managedUserDTO.getLastName());
             user.setEmail(managedUserDTO.getEmail());
             user.setActivated(managedUserDTO.isActivated());
             user.setLangKey(managedUserDTO.getLangKey());
             Set<Authority> authorities = user.getAuthorities();
             authorities.clear();
             managedUserDTO
                 .getAuthorities()
                 .stream()
                 .forEach(authority -> authorities.add(authorityRepository.findOne(authority)));
             return ResponseEntity.ok()
                 .headers(
                     HeaderUtil.createAlert("userManagement.updated", managedUserDTO.getLogin()))
                 .body(new ManagedUserDTO(userRepository.findOne(managedUserDTO.getId())));
           })
       .orElseGet(() -> new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR));
 }
  /**
   * POST /users : Creates a new user.
   *
   * <p>Creates a new user if the login and email are not already used, and sends an mail with an
   * activation link. The user needs to be activated on creation.
   *
   * @param managedUserDTO the user to create
   * @param request the HTTP request
   * @return the ResponseEntity with status 201 (Created) and with body the new user, or with status
   *     400 (Bad Request) if the login or email is already in use
   * @throws URISyntaxException if the Location URI syntaxt is incorrect
   */
  @RequestMapping(
      value = "/users",
      method = RequestMethod.POST,
      produces = MediaType.APPLICATION_JSON_VALUE)
  @Timed
  @Secured(AuthoritiesConstants.ADMIN)
  public ResponseEntity<?> createUser(
      @RequestBody ManagedUserDTO managedUserDTO, HttpServletRequest request)
      throws URISyntaxException {
    log.debug("REST request to save User : {}", managedUserDTO);

    // Lowercase the user login before comparing with database
    if (userRepository.findOneByLogin(managedUserDTO.getLogin().toLowerCase()).isPresent()) {
      return ResponseEntity.badRequest()
          .headers(
              HeaderUtil.createFailureAlert("userManagement", "userexists", "Login already in use"))
          .body(null);
    } else if (userRepository.findOneByEmail(managedUserDTO.getEmail()).isPresent()) {
      return ResponseEntity.badRequest()
          .headers(
              HeaderUtil.createFailureAlert(
                  "userManagement", "emailexists", "Email already in use"))
          .body(null);
    } else {
      User newUser = userService.createUser(managedUserDTO);
      String baseUrl =
          request.getScheme()
              + // "http"
              "://"
              + // "://"
              request.getServerName()
              + // "myhost"
              ":"
              + // ":"
              request.getServerPort()
              + // "80"
              request.getContextPath(); // "/myContextPath" or "" if deployed in root context
      mailService.sendCreationEmail(newUser, baseUrl);
      return ResponseEntity.created(new URI("/api/users/" + newUser.getLogin()))
          .headers(HeaderUtil.createAlert("userManagement.created", newUser.getLogin()))
          .body(newUser);
    }
  }