// Path: src/main/java/com/lyubenblagoev/postfixrest/NotFoundException.java
// public class NotFoundException extends RuntimeException {
// 
// 	private static final long serialVersionUID = -1967579868614870552L;
// 
// 	public NotFoundException() {
// 	}
// 
// 	public NotFoundException(String message) {
// 		super(message);
// 	}
// 
// 	public NotFoundException(Throwable cause) {
// 		super(cause);
// 	}
// 
// 	public NotFoundException(String message, Throwable cause) {
// 		super(message, cause);
// 	}
// 
// 	public NotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
// 		super(message, cause, enableSuppression, writableStackTrace);
// 	}
// 
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/controller/model/UserUpdateRequest.java
// @PasswordsMatches
// public class UserUpdateRequest implements PasswordConfirmable {
// 
//     @NotEmpty
//     @Email
//     private String email;
// 
//     private String password;
// 
//     private String passwordConfirmation;
// 
//     @NotBlank
//     private String oldPassword;
// 
//     public String getEmail() {
//         return email;
//     }
// 
//     public void setEmail(String email) {
//         this.email = email;
//     }
// 
//     @Override
//     public String getPassword() {
//         return password;
//     }
// 
//     public void setPassword(String password) {
//         this.password = password;
//     }
// 
//     @Override
//     public String getPasswordConfirmation() {
//         return passwordConfirmation;
//     }
// 
//     public void setPasswordConfirmation(String passwordConfirmation) {
//         this.passwordConfirmation = passwordConfirmation;
//     }
// 
//     public String getOldPassword() {
//         return oldPassword;
//     }
// 
//     public void setOldPassword(String oldPassword) {
//         this.oldPassword = oldPassword;
//     }
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/service/UserService.java
// public interface UserService {
//     Optional<User> findByEmail(String email);
// 
//     Optional<User> findByEmailAndPassword(String email, String password);
// 
//     Optional<User> update(UserChangeRequest userChangeRequest);
// 
//     void addDeviceTokens(String email, DeviceInformation device, String refreshToken, Date refreshTokenExpirationDate);
// 
//     void updateDeviceTokens(String email, DeviceInformation device, String previousRefreshToken,
//             String newRefreshToken, Date refreshTokenExpirationDate);
// 
//     void removeDeviceToken(String email, String refreshToken);
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/service/model/UserChangeRequest.java
// @PasswordsMatches
// public class UserChangeRequest implements PasswordConfirmable {
// 
//     private Long id;
// 
//     @NotEmpty
//     @Email
//     private String email;
// 
//     private String password;
// 
//     private String passwordConfirmation;
// 
//     @NotBlank
//     private String oldPassword;
// 
//     public UserChangeRequest() {
//     }
// 
//     public UserChangeRequest(@NotEmpty @Email String email,
//                              String password,
//                              String passwordConfirmation) {
//         this.email = email;
//         this.password = password;
//         this.passwordConfirmation = passwordConfirmation;
//     }
// 
//     public Long getId() {
//         return id;
//     }
// 
//     public void setId(Long id) {
//         this.id = id;
//     }
// 
//     public String getEmail() {
//         return email;
//     }
// 
//     public void setEmail(String email) {
//         this.email = email;
//     }
// 
//     @Override
//     public String getPassword() {
//         return password;
//     }
// 
//     public void setPassword(String password) {
//         this.password = password;
//     }
// 
//     @Override
//     public String getPasswordConfirmation() {
//         return passwordConfirmation;
//     }
// 
//     public void setPasswordConfirmation(String passwordConfirmation) {
//         this.passwordConfirmation = passwordConfirmation;
//     }
// 
//     public String getOldPassword() {
//         return oldPassword;
//     }
// 
//     public void setOldPassword(String oldPassword) {
//         this.oldPassword = oldPassword;
//     }
// }


import com.lyubenblagoev.postfixrest.NotFoundException;
import com.lyubenblagoev.postfixrest.controller.model.UserUpdateRequest;
import com.lyubenblagoev.postfixrest.service.UserService;
import com.lyubenblagoev.postfixrest.service.model.UserChangeRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
package com.lyubenblagoev.postfixrest.controller;



@RestController
@RequestMapping("/api/v1/users")
public class UserController {

    private static final String INVALID_USER_CREDENTIALS_MESSAGE = "Invalid user credentials";

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PutMapping("/{login:.+}")
    public ResponseEntity<?> updateUser(@Valid @RequestBody UserUpdateRequest userUpdateRequest,
                                        @PathVariable("login") String currentLogin) {
        String currentPassword = userUpdateRequest.getOldPassword();
        UserChangeRequest userChangeRequest = new UserChangeRequest(
                userUpdateRequest.getEmail(),
                userUpdateRequest.getPassword(),
                userUpdateRequest.getPasswordConfirmation());
        return userService.findByEmailAndPassword(currentLogin, currentPassword)
                .map(u -> {
                    userChangeRequest.setId(u.getId());
                    userService.update(userChangeRequest);
                    return ResponseEntity.ok().build();
                })
// Path: src/main/java/com/lyubenblagoev/postfixrest/NotFoundException.java
// public class NotFoundException extends RuntimeException {
// 
// 	private static final long serialVersionUID = -1967579868614870552L;
// 
// 	public NotFoundException() {
// 	}
// 
// 	public NotFoundException(String message) {
// 		super(message);
// 	}
// 
// 	public NotFoundException(Throwable cause) {
// 		super(cause);
// 	}
// 
// 	public NotFoundException(String message, Throwable cause) {
// 		super(message, cause);
// 	}
// 
// 	public NotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
// 		super(message, cause, enableSuppression, writableStackTrace);
// 	}
// 
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/controller/model/UserUpdateRequest.java
// @PasswordsMatches
// public class UserUpdateRequest implements PasswordConfirmable {
// 
//     @NotEmpty
//     @Email
//     private String email;
// 
//     private String password;
// 
//     private String passwordConfirmation;
// 
//     @NotBlank
//     private String oldPassword;
// 
//     public String getEmail() {
//         return email;
//     }
// 
//     public void setEmail(String email) {
//         this.email = email;
//     }
// 
//     @Override
//     public String getPassword() {
//         return password;
//     }
// 
//     public void setPassword(String password) {
//         this.password = password;
//     }
// 
//     @Override
//     public String getPasswordConfirmation() {
//         return passwordConfirmation;
//     }
// 
//     public void setPasswordConfirmation(String passwordConfirmation) {
//         this.passwordConfirmation = passwordConfirmation;
//     }
// 
//     public String getOldPassword() {
//         return oldPassword;
//     }
// 
//     public void setOldPassword(String oldPassword) {
//         this.oldPassword = oldPassword;
//     }
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/service/UserService.java
// public interface UserService {
//     Optional<User> findByEmail(String email);
// 
//     Optional<User> findByEmailAndPassword(String email, String password);
// 
//     Optional<User> update(UserChangeRequest userChangeRequest);
// 
//     void addDeviceTokens(String email, DeviceInformation device, String refreshToken, Date refreshTokenExpirationDate);
// 
//     void updateDeviceTokens(String email, DeviceInformation device, String previousRefreshToken,
//             String newRefreshToken, Date refreshTokenExpirationDate);
// 
//     void removeDeviceToken(String email, String refreshToken);
// }
// 
// Path: src/main/java/com/lyubenblagoev/postfixrest/service/model/UserChangeRequest.java
// @PasswordsMatches
// public class UserChangeRequest implements PasswordConfirmable {
// 
//     private Long id;
// 
//     @NotEmpty
//     @Email
//     private String email;
// 
//     private String password;
// 
//     private String passwordConfirmation;
// 
//     @NotBlank
//     private String oldPassword;
// 
//     public UserChangeRequest() {
//     }
// 
//     public UserChangeRequest(@NotEmpty @Email String email,
//                              String password,
//                              String passwordConfirmation) {
//         this.email = email;
//         this.password = password;
//         this.passwordConfirmation = passwordConfirmation;
//     }
// 
//     public Long getId() {
//         return id;
//     }
// 
//     public void setId(Long id) {
//         this.id = id;
//     }
// 
//     public String getEmail() {
//         return email;
//     }
// 
//     public void setEmail(String email) {
//         this.email = email;
//     }
// 
//     @Override
//     public String getPassword() {
//         return password;
//     }
// 
//     public void setPassword(String password) {
//         this.password = password;
//     }
// 
//     @Override
//     public String getPasswordConfirmation() {
//         return passwordConfirmation;
//     }
// 
//     public void setPasswordConfirmation(String passwordConfirmation) {
//         this.passwordConfirmation = passwordConfirmation;
//     }
// 
//     public String getOldPassword() {
//         return oldPassword;
//     }
// 
//     public void setOldPassword(String oldPassword) {
//         this.oldPassword = oldPassword;
//     }
// }


// Path: src/main/java/com/lyubenblagoev/postfixrest/controller/UserController.java
import com.lyubenblagoev.postfixrest.NotFoundException;
import com.lyubenblagoev.postfixrest.controller.model.UserUpdateRequest;
import com.lyubenblagoev.postfixrest.service.UserService;
import com.lyubenblagoev.postfixrest.service.model.UserChangeRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;

package com.lyubenblagoev.postfixrest.controller;



@RestController
@RequestMapping("/api/v1/users")
public class UserController {

    private static final String INVALID_USER_CREDENTIALS_MESSAGE = "Invalid user credentials";

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @PutMapping("/{login:.+}")
    public ResponseEntity<?> updateUser(@Valid @RequestBody UserUpdateRequest userUpdateRequest,
                                        @PathVariable("login") String currentLogin) {
        String currentPassword = userUpdateRequest.getOldPassword();
        UserChangeRequest userChangeRequest = new UserChangeRequest(
                userUpdateRequest.getEmail(),
                userUpdateRequest.getPassword(),
                userUpdateRequest.getPasswordConfirmation());
        return userService.findByEmailAndPassword(currentLogin, currentPassword)
                .map(u -> {
                    userChangeRequest.setId(u.getId());
                    userService.update(userChangeRequest);
                    return ResponseEntity.ok().build();
                })
                .orElseThrow(() -> new NotFoundException(INVALID_USER_CREDENTIALS_MESSAGE));