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

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Collections;
import java.util.Set;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.interceptor.Fault;
import org.apache.cxf.message.Message;
import org.apache.cxf.phase.PhaseInterceptor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Cet interceptor CXF sauvegarde l'enveloppe SOAP avant son envoi de manière à permettre 
 * à l'intercepteur principal @PAOSOutInterceptor de la rejouer à la fin du processus d'authentification.
 * @author ASIP Santé
 */
public class PAOSOutInterceptor implements
    PhaseInterceptor<SoapMessage>{

    
     public void handleFault(SoapMessage t) {
    }

    public Set<String> getAfter() {
        return Collections.EMPTY_SET;
    }

    public Set<String> getBefore() {
        return Collections.EMPTY_SET;
    }

    public String getId() {
        return toString();
    }

    public String getPhase() {
        return "pre-stream";
    }

    public Collection<PhaseInterceptor<? extends Message>> getAdditionalInterceptors() {
        return Collections.EMPTY_SET;
    }

    @Override
    public void handleMessage(SoapMessage t) throws Fault {
        LOGGER.debug(t.getContentFormats().toString());
        final OutputStream ostr=t.getContent(OutputStream.class);
        LOGGER.debug("used: "+ostr.getClass().getName());
        OutputStream wrapper=new OutputStreamTee(ostr);
        t.setContent(OutputStream.class, wrapper);
        t.setContent(OutputStreamTee.class, wrapper);
    }
    private static final Logger LOGGER = LoggerFactory.getLogger(PAOSOutInterceptor.class);

    /**
     * OutputStream est un buffer qui autorise la duplication de l'enveloppe SOAP lors de son expédition vers l'EndPoint.
     * Permet de garder une copie du message de manière transparente sans avoir besoin de connaître
     * les services appelés et les autres interceptors déployés en sortie.
     * @author ASIP Santé
     */
    public static class OutputStreamTee extends OutputStream {
        private ByteArrayOutputStream buffer=new ByteArrayOutputStream();
        private final OutputStream ostr;

        public OutputStreamTee(OutputStream ostr) {
            this.ostr = ostr;
        }

        /**
         * Permet de récupérer le contenu de l'enveloppe SOAP enregistrée.
         * @return une copie au byte près du contenu de l'enveloppe sortante.
         */
        public byte[] getData(){
            return buffer.toByteArray();
        }
        
        @Override
        public void write(int b) throws IOException {
            ostr.write(b);
            buffer.write(b);
        }

            @Override
            public void close() throws IOException {
                super.close(); //To change body of generated methods, choose Tools | Templates.
                ostr.close();
                LOGGER.debug("wrapper closed, buffer got: \n"+buffer.toString("utf-8"));
            }
    }


}
