// Path: identity-service/src/main/java/eu/nimble/core/infrastructure/identity/constants/GlobalConstants.java
// public class GlobalConstants {
// 
//     public static final String PARTY_NAME_STRING = "partyName";
//     public static final String ASCENDING_STRING = "asc";
//     public static final String DESCENDING_STRING = "desc";
//     public static final String JWT_SUBJECT_ATTRIBUTE_STRING = "sub";
//     public static final String JWT_EXPIRY_ATTRIBUTE_STRING = "exp";
//     public static final String JWT_TYPE_ATTRIBUTE_STRING = "type";
//     public static final String EMAIL_STRING = "email";
//     public static final String USER_NAME_STRING = "username";
// 
//     // OAUTH Related Constants
//     public static final String CLIENT_CREDENTIALS_FLOW = "client_credentials";
//     public static final String AUTHORIZATION_CODE_FLOW = "authorization_code";
//     public static final String REFRESH_TOKEN_FLOW = "refresh_token";
// 
// }
// 
// Path: identity-service/src/main/java/eu/nimble/core/infrastructure/identity/system/dto/oauth/Token.java
// public class Token {
// 
//     private String access_token = null;
//     private String expires_in = null;
//     private String refresh_expires_in = null;
//     private String refresh_token = null;
//     private String token_type = null;
//     private String id_token = null;
//     private String session_state = null;
//     private String scope = null;
//     private String code = null;
//     private String redirect_URL = null;
// 
//     public String getAccess_token() {
//         return access_token;
//     }
// 
//     public void setAccess_token(String access_token) {
//         this.access_token = access_token;
//     }
// 
//     public String getExpires_in() {
//         return expires_in;
//     }
// 
//     public void setExpires_in(String expires_in) {
//         this.expires_in = expires_in;
//     }
// 
//     public String getRefresh_expires_in() {
//         return refresh_expires_in;
//     }
// 
//     public void setRefresh_expires_in(String refresh_expires_in) {
//         this.refresh_expires_in = refresh_expires_in;
//     }
// 
//     public String getRefresh_token() {
//         return refresh_token;
//     }
// 
//     public void setRefresh_token(String refresh_token) {
//         this.refresh_token = refresh_token;
//     }
// 
//     public String getToken_type() {
//         return token_type;
//     }
// 
//     public void setToken_type(String token_type) {
//         this.token_type = token_type;
//     }
// 
//     public String getId_token() {
//         return id_token;
//     }
// 
//     public void setId_token(String id_token) {
//         this.id_token = id_token;
//     }
// 
//     public String getSession_state() {
//         return session_state;
//     }
// 
//     public void setSession_state(String session_state) {
//         this.session_state = session_state;
//     }
// 
//     public String getScope() {
//         return scope;
//     }
// 
//     public void setScope(String scope) {
//         this.scope = scope;
//     }
// 
//     public String getCode() {
//         return code;
//     }
// 
//     public void setCode(String code) {
//         this.code = code;
//     }
// 
//     public String getRedirect_URL() {
//         return redirect_URL;
//     }
// 
//     public void setRedirect_URL(String redirect_URL) {
//         this.redirect_URL = redirect_URL;
//     }
// }


import com.auth0.jwt.JWT;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import eu.nimble.core.infrastructure.identity.constants.GlobalConstants;
import eu.nimble.core.infrastructure.identity.system.dto.oauth.Token;
import org.keycloak.representations.idm.UserRepresentation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import java.util.List;
package eu.nimble.core.infrastructure.identity.service;


@Service
public class FederationService {

    private final Logger logger = LoggerFactory.getLogger(FederationService.class);

    @Value("${nimble.oauth.federationClient.accessTokenUri}")
    private String accessTokenUri;

    @Value("${nimble.oauth.federationClient.clientId}")
    private String clientId;

    @Value("${nimble.oauth.federationClient.clientSecret}")
    private String clientSecret;

    @Value("${nimble.oauth.federationClient.redirectUri}")
    private String redirectUri;

    @Value("${nimble.oauth.eFactoryClient.clientId}")
    private String eFactoryClientId;

    @Value("${nimble.oauth.eFactoryClient.clientSecret}")
    private String eFactoryClientSecret;

    @Value("${nimble.oauth.eFactoryClient.accessTokenUri}")
    private String eFactoryAccessTokenUri;

    @Value("${nimble.oauth.eFactoryClient.userDetailsUri}")
    private String eFactoryUserDetailsUri;

    public Token exchangeToken(String trustedToken) {
        // TODO verify the signature
// Path: identity-service/src/main/java/eu/nimble/core/infrastructure/identity/constants/GlobalConstants.java
// public class GlobalConstants {
// 
//     public static final String PARTY_NAME_STRING = "partyName";
//     public static final String ASCENDING_STRING = "asc";
//     public static final String DESCENDING_STRING = "desc";
//     public static final String JWT_SUBJECT_ATTRIBUTE_STRING = "sub";
//     public static final String JWT_EXPIRY_ATTRIBUTE_STRING = "exp";
//     public static final String JWT_TYPE_ATTRIBUTE_STRING = "type";
//     public static final String EMAIL_STRING = "email";
//     public static final String USER_NAME_STRING = "username";
// 
//     // OAUTH Related Constants
//     public static final String CLIENT_CREDENTIALS_FLOW = "client_credentials";
//     public static final String AUTHORIZATION_CODE_FLOW = "authorization_code";
//     public static final String REFRESH_TOKEN_FLOW = "refresh_token";
// 
// }
// 
// Path: identity-service/src/main/java/eu/nimble/core/infrastructure/identity/system/dto/oauth/Token.java
// public class Token {
// 
//     private String access_token = null;
//     private String expires_in = null;
//     private String refresh_expires_in = null;
//     private String refresh_token = null;
//     private String token_type = null;
//     private String id_token = null;
//     private String session_state = null;
//     private String scope = null;
//     private String code = null;
//     private String redirect_URL = null;
// 
//     public String getAccess_token() {
//         return access_token;
//     }
// 
//     public void setAccess_token(String access_token) {
//         this.access_token = access_token;
//     }
// 
//     public String getExpires_in() {
//         return expires_in;
//     }
// 
//     public void setExpires_in(String expires_in) {
//         this.expires_in = expires_in;
//     }
// 
//     public String getRefresh_expires_in() {
//         return refresh_expires_in;
//     }
// 
//     public void setRefresh_expires_in(String refresh_expires_in) {
//         this.refresh_expires_in = refresh_expires_in;
//     }
// 
//     public String getRefresh_token() {
//         return refresh_token;
//     }
// 
//     public void setRefresh_token(String refresh_token) {
//         this.refresh_token = refresh_token;
//     }
// 
//     public String getToken_type() {
//         return token_type;
//     }
// 
//     public void setToken_type(String token_type) {
//         this.token_type = token_type;
//     }
// 
//     public String getId_token() {
//         return id_token;
//     }
// 
//     public void setId_token(String id_token) {
//         this.id_token = id_token;
//     }
// 
//     public String getSession_state() {
//         return session_state;
//     }
// 
//     public void setSession_state(String session_state) {
//         this.session_state = session_state;
//     }
// 
//     public String getScope() {
//         return scope;
//     }
// 
//     public void setScope(String scope) {
//         this.scope = scope;
//     }
// 
//     public String getCode() {
//         return code;
//     }
// 
//     public void setCode(String code) {
//         this.code = code;
//     }
// 
//     public String getRedirect_URL() {
//         return redirect_URL;
//     }
// 
//     public void setRedirect_URL(String redirect_URL) {
//         this.redirect_URL = redirect_URL;
//     }
// }


// Path: identity-service/src/main/java/eu/nimble/core/infrastructure/identity/service/FederationService.java
import com.auth0.jwt.JWT;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;
import eu.nimble.core.infrastructure.identity.constants.GlobalConstants;
import eu.nimble.core.infrastructure.identity.system.dto.oauth.Token;
import org.keycloak.representations.idm.UserRepresentation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import java.util.List;

package eu.nimble.core.infrastructure.identity.service;


@Service
public class FederationService {

    private final Logger logger = LoggerFactory.getLogger(FederationService.class);

    @Value("${nimble.oauth.federationClient.accessTokenUri}")
    private String accessTokenUri;

    @Value("${nimble.oauth.federationClient.clientId}")
    private String clientId;

    @Value("${nimble.oauth.federationClient.clientSecret}")
    private String clientSecret;

    @Value("${nimble.oauth.federationClient.redirectUri}")
    private String redirectUri;

    @Value("${nimble.oauth.eFactoryClient.clientId}")
    private String eFactoryClientId;

    @Value("${nimble.oauth.eFactoryClient.clientSecret}")
    private String eFactoryClientSecret;

    @Value("${nimble.oauth.eFactoryClient.accessTokenUri}")
    private String eFactoryAccessTokenUri;

    @Value("${nimble.oauth.eFactoryClient.userDetailsUri}")
    private String eFactoryUserDetailsUri;

    public Token exchangeToken(String trustedToken) {
        // TODO verify the signature
        long exp = JWT.decode(trustedToken).getClaim(GlobalConstants.JWT_EXPIRY_ATTRIBUTE_STRING).asLong();