package enea.lecservice.controllers;

import enea.lecservice.models.dto.ServiceResponse;
import enea.lecservice.security.IUserInfoService;
import enea.lecservice.security.InMemoryUserInfoService;
import enea.lecservice.security.controller.AbstractSecurityController;
import enea.lecservice.security.dto.AuthRequest;
import enea.lecservice.security.dto.UserInfo;
import enea.lecservice.security.jwt.JWTUtil;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import lombok.extern.log4j.Log4j2;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.web.bind.annotation.*;

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;

@Log4j2
@CrossOrigin("*")
@RestController
@RequestMapping("/auth")
public class AuthController extends AbstractSecurityController {
    @Value("${authentication.endpoint}")
    protected String authenticationEndpoint;

    public AuthController(@NonNull AuthenticationManager authenticationManager, 
    		@NonNull InMemoryUserInfoService userDetailsService, 
    		@NonNull JWTUtil jwtUtil, 
    		@NonNull IUserInfoService userInfoService) {
        super(authenticationManager, userDetailsService, jwtUtil, userInfoService);
    }

    @GetMapping("/")
    public String index() {
        return "Auth attivo.";
    }

    @GetMapping(value = "/authenticate")
    public void initAuthentication(HttpServletResponse httpServletResponse) {
        httpServletResponse.setHeader("Location", authenticationEndpoint);
        httpServletResponse.setStatus(HttpStatus.PERMANENT_REDIRECT.value());
        //return new ResponseEntity(new HttpHeaders(), HttpStatus.MOVED_PERMANENTLY);
    }

    @PostMapping(value = "/authenticate")
    public ResponseEntity<ServiceResponse<?>> authenticate(@RequestBody AuthRequest request) throws Exception {
         return super.authenticate(request);
    }
    
    @PostMapping(value = "/authenticateWithToken")
    public ResponseEntity<ServiceResponse<?>> authenticateWithToken(@RequestBody Token token) throws Exception {
    	return super.authenticateWithToken(token.getToken());
    }

    @PostMapping(value = "/logout")
    public ServiceResponse logout(HttpServletRequest request) {
        Optional<String> jwt = jwtUtil.getTokenFromRequest(request);
        if (jwt.isPresent()) {
            String username = jwtUtil.extractUsername(jwt.get());
            UserInfo userInfo = userDetailsService.loadUserByUsername(username);

            // Logout from ENEA WS
            ServiceResponse logoutResult = userInfoService.logout(userInfo);

            userDetailsService.deleteUser(username);
            jwtUtil.expireToken(jwt.get());

            if (!logoutResult.isSuccess())
                return logoutResult;

            return ServiceResponse.Success();
        }

        return ServiceResponse.Error("Errore del server. Contattare l'amministratore");
    }
    @Getter @Setter
    private static class Token {
    	String token;
    }
}


