/*
 *     Copyright (C) 2015 ASIP Santé
 */
package fr.asipsante.mss.connectkit.paos;

import java.io.ByteArrayInputStream;
import java.io.IOException;

import javax.net.ssl.HttpsURLConnection;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fr.asipsante.mss.connectkit.connection.HttpsConnectionFactory;
import fr.asipsante.mss.connectkit.connection.SSLSecurityException;
import java.net.URL;

/**
 * Variante de protocole SAML2 avec un seul appel à l'IDP. Utiliser pour les
 * stratégies d'authentification directes telles que la double authentification
 * SSL (par certificat logiciel ou par carte).
 * 
 * @author ASIP Santé
 *
 */
public class DirectAuthSaml2Driver extends AbstractSaml2Driver {

    private static final Logger LOGGER = LoggerFactory
            .getLogger(DirectAuthSaml2Driver.class);
    /**
	 * 
	 */
    private static final String CPSIDNAT_HEADER_NAME = "CPSIDNAT";
    private String idNat;

    /**
     * 
     * @param defaultEncoding
     *            encodage par défaut pour les échanges
     * @param connectionFactory
     *            connectionfactory pour l'application de la stratégie
     *            d'authentification SSL
     * @param authHostname
     *            nom de l'hôte de l'IDP
     * @param authPort
     *            port d'écoute de l'IDP (-1 pour la valeur par défaut)
     * @param authPath
     *            composante chemin de l'URL de l'IDP
     */
    public DirectAuthSaml2Driver(String defaultEncoding,
            HttpsConnectionFactory connectionFactory, String authHostname,
            int authPort, String authPath) {
        super(defaultEncoding, connectionFactory, authHostname, authPort,
                authPath);
    }

    /**
     * 
     * @param defaultEncoding
     *            encodage par défaut pour les échanges
     * @param connectionFactory
     *            connectionFactory pour l'application de la stratégie
     *            d'authentification SSL
     * @param authHostname
     *            nom de l'hôte de l'IDP
     * @param authPort
     *            port d'écoute de l'IDP (-1 pour la valeur par défaut)
     * @param authPath
     *            composante chemin de l'URL de l'IDP
     * @param idNat
     *            idNat du PS
     */
    public DirectAuthSaml2Driver(String defaultEncoding,
            HttpsConnectionFactory connectionFactory, String authHostname,
            int authPort, String authPath, String idNat) {
        this(defaultEncoding, connectionFactory, authHostname, authPort,
                authPath);
        this.idNat = idNat;
    }

    /**
     * 
     * @param defaultEncoding
     *            encodage par défaut pour les échanges
     * @param connectionFactory
     *            connection factory pour l'application de la stratégie
     *            d'authentification SSL
     * @param authUrl
     *            URL de l'IDP
     * @param idNat
     *            idNat du PS
     */
    public DirectAuthSaml2Driver(String defaultEncoding,
            HttpsConnectionFactory connectionFactory, URL authUrl, String idNat) {
        this(defaultEncoding, connectionFactory, authUrl.getHost(), authUrl
                .getPort(), authUrl.getPath(), idNat);
    }

    /**
     * Setter idNat, pour reconfigurer l'idNat avant appel.
     * 
     * @param idNat
     */
    public void setIdNat(String idNat) {
        this.idNat = idNat;
    }

    @Override
    public byte[] getSamlAssertionFromAuthService(String sslProtocolSpec,
            byte[] xmlContent) throws IOException, SSLSecurityException {
        HttpsURLConnection authConnection = createConnection(sslProtocolSpec);
        addConnectionHeaders(authConnection);

        int authResponseCode = getConnUtil().sendPost(authConnection,
                new ByteArrayInputStream(xmlContent));

        LOGGER.debug("Authentication service return code:" + authResponseCode);
        byte[] authResponse = getConnUtil().getResponse(authConnection);
        authConnection.disconnect();
        return authResponse;
    }

    @Override
    protected void addConnectionHeaders(HttpsURLConnection authConnection) {
        authConnection.addRequestProperty(CPSIDNAT_HEADER_NAME, idNat);
    }
}