package enea.lecservice.security.controller;

import enea.lecservice.models.dto.ServiceResponse;
import enea.lecservice.security.IUserInfoService;
import enea.lecservice.security.InMemoryUserInfoService;
import enea.lecservice.security.dto.AuthRequest;
import enea.lecservice.security.dto.UserInfo;
import enea.lecservice.security.jwt.JWTUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.log4j.Log4j2;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;

@Log4j2
@Controller
@RequiredArgsConstructor
public class AbstractSecurityController {

    protected final AuthenticationManager authenticationManager;
    protected final InMemoryUserInfoService userDetailsService;
    protected final JWTUtil jwtUtil;
    protected final IUserInfoService userInfoService;
    
    public ResponseEntity<ServiceResponse<?>> authenticate(AuthRequest request) throws Exception {
        authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(request.getUsername(), request.getPassword()));
        final UserInfo userInfo = userDetailsService.loadUserByUsername(request.getUsername());

        String newToken;
        if (userInfo.getToken() != null)
            newToken = jwtUtil.generateToken(userInfo, userInfo.getToken().getCreation(), userInfo.getToken().getExpiration());
        else
            newToken = jwtUtil.generateToken(userInfo);

        return ResponseEntity.ok(ServiceResponse.Success(new Object () {
            public String token = newToken;
            public UserInfo user = userInfo;
        }));
    }

	public ResponseEntity<ServiceResponse<?>> authenticateWithToken(String token) throws Exception {
		Authentication user = authenticationManager.authenticate(new UsernamePasswordAuthenticationToken(token, ""));
		final UserInfo userInfo = userDetailsService.loadUserByUsername(user.getName());
		
		 String newToken;
	        if (userInfo.getToken() != null)
	            newToken = jwtUtil.generateToken(userInfo, userInfo.getToken().getCreation(), userInfo.getToken().getExpiration());
	        else
	            newToken = jwtUtil.generateToken(userInfo);
		
		return ResponseEntity.ok(ServiceResponse.Success(new Object () {
            public String token = newToken;
            public UserInfo user = userInfo;
        }));
	}
}
