package eu.eudat.logic.security.validators.configurableProvider;

import eu.eudat.exceptions.security.NullEmailException;
import eu.eudat.logic.proxy.config.configloaders.ConfigLoader;

import eu.eudat.logic.security.customproviders.ConfigurableProvider.ConfigurableProviderCustomProvider;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.ConfigurableProviderUser;
import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProvider;
import eu.eudat.logic.security.validators.TokenValidator;
import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderRequest;
import eu.eudat.logic.security.validators.configurableProvider.helpers.ConfigurableProviderResponseToken;
import eu.eudat.logic.services.operations.authentication.AuthenticationService;
import eu.eudat.models.data.login.LoginInfo;
import eu.eudat.models.data.loginprovider.LoginProviderUser;
import eu.eudat.models.data.security.Principal;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.stream.Collectors;

@Component("configurableProviderTokenValidator")
public class ConfigurableProviderTokenValidator implements TokenValidator {

	private ConfigurableProviderCustomProvider configurableProvider;
	private AuthenticationService nonVerifiedUserAuthenticationService;
	private ConfigLoader configLoader;

	public ConfigurableProviderTokenValidator(ConfigurableProviderCustomProvider configurableProvider, AuthenticationService nonVerifiedUserAuthenticationService, ConfigLoader configLoader) {
		this.configurableProvider = configurableProvider;
		this.nonVerifiedUserAuthenticationService = nonVerifiedUserAuthenticationService;
		this.configLoader = configLoader;
	}

	public ConfigurableProviderResponseToken getAccessToken(ConfigurableProviderRequest configurableProviderRequest) {
		ConfigurableProvider provider = getConfigurableProviderFromId(configurableProviderRequest.getConfigurableLoginId());
		return this.configurableProvider.getAccessToken(configurableProviderRequest.getCode(),
				provider.getRedirect_uri(), provider.getClientId(), provider.getClientSecret(),
				provider.getAccess_token_url(), provider.getGrant_type(), provider.getToken().getAccess_token(), provider.getToken().getExpires_in());
	}
	@Override
	public Principal validateToken(LoginInfo credentials) throws NullEmailException {
		String configurableLoginId = ((Map) credentials.getData()).get("configurableLoginId").toString();
		ConfigurableProvider configurableProvider = getConfigurableProviderFromId(configurableLoginId);
		ConfigurableProviderUser configurableUser = this.configurableProvider.getUser(credentials.getTicket(), configurableProvider.getUser());
		LoginProviderUser user = new LoginProviderUser();
		user.setId(configurableUser.getId());
		user.setEmail(configurableUser.getEmail());
		user.setName(configurableUser.getName());
		user.setProvider(credentials.getProvider());
		user.setSecret(credentials.getTicket());

		return this.nonVerifiedUserAuthenticationService.Touch(user);
	}

	private ConfigurableProvider getConfigurableProviderFromId(String configurableId) {
		return this.configLoader.getConfigurableProviders().getProviders().stream()
				.filter(prov -> prov.getConfigurableLoginId().equals(configurableId))
				.collect(Collectors.toList())
				.get(0);
	}
}
