/**
 * 
 */
package de.bstly.board.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ResolvableType;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.client.registration.ClientRegistration;
import org.springframework.security.oauth2.client.registration.ClientRegistrationRepository;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.google.common.collect.Lists;

import de.bstly.board.controller.support.EntityResponseStatusException;
import de.bstly.board.security.LocalUserDetails;

/**
 * The Class AuthenticationController.
 */
@RestController
@RequestMapping("/auth")
public class AuthenticationController extends BaseController {

	private static String authorizationRequestBaseUri = "oauth2/authorization";

	@Autowired
	private ClientRegistrationRepository clientRegistrationRepository;

	/**
	 * Me.
	 *
	 * @return the object
	 */
	@GetMapping
	public Object me() {
		Authentication auth = SecurityContextHolder.getContext().getAuthentication();
		if (auth != null && auth.getPrincipal() instanceof LocalUserDetails) {
			return (LocalUserDetails) auth.getPrincipal();
		}

		throw new EntityResponseStatusException(HttpStatus.UNAUTHORIZED);
	}

	/**
	 * Gets the external login urls.
	 *
	 * @return the external login urls
	 */
	@SuppressWarnings("unchecked")
	@GetMapping("external")
	public List<Client> getExternalLoginUrls() {
		List<Client> clients = Lists.newArrayList();
		Iterable<ClientRegistration> clientRegistrations = null;
		ResolvableType type = ResolvableType.forInstance(clientRegistrationRepository)
				.as(Iterable.class);
		if (type != ResolvableType.NONE
				&& ClientRegistration.class.isAssignableFrom(type.resolveGenerics()[0])) {
			clientRegistrations = (Iterable<ClientRegistration>) clientRegistrationRepository;
		}

		clientRegistrations
				.forEach(registration -> clients.add(new Client(registration.getRegistrationId(),
						authorizationRequestBaseUri
								+ "/"
								+ registration.getRegistrationId())));

		return clients;
	}

	/**
	 * The Class Client.
	 */
	protected static class Client {

		private String id;

		private String loginUrl;

		/**
		 * Instantiates a new client.
		 *
		 * @param id the id
		 * @param loginUrl the login url
		 */
		public Client(String id, String loginUrl) {
			super();
			this.id = id;
			this.loginUrl = loginUrl;
		}

		/**
		 * Gets the id.
		 *
		 * @return the id
		 */
		public String getId() {
			return id;
		}

		/**
		 * Sets the id.
		 *
		 * @param id the new id
		 */
		public void setId(String id) {
			this.id = id;
		}

		/**
		 * Gets the login url.
		 *
		 * @return the login url
		 */
		public String getLoginUrl() {
			return loginUrl;
		}

		/**
		 * Sets the login url.
		 *
		 * @param loginUrl the new login url
		 */
		public void setLoginUrl(String loginUrl) {
			this.loginUrl = loginUrl;
		}

	}
}
