/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License. You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.cxf.ext.logging.event;

import java.io.StringReader;
import java.io.StringWriter;

import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamWriter;

import com.ctc.wstx.exc.WstxLazyException;
import org.apache.cxf.staxutils.PrettyPrintXMLStreamWriter;
import org.apache.cxf.staxutils.StaxUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Formats the log message with indents.
 * If the log message was truncated then this filter might additionally cut incomplete tags
 */
public class PrettyLoggingFilter implements LogEventSender {
    private static final Logger LOG = LoggerFactory.getLogger(PrettyLoggingFilter.class);
    private LogEventSender next;
    private boolean prettyLogging;

    public PrettyLoggingFilter(LogEventSender next) {
        this.next = next;
        this.prettyLogging = false;
    }

    @Override
    public void send(LogEvent event) {
        if (shouldPrettyPrint(event)) {
            event.setPayload(getPrettyMessage(event));
        }
        next.send(event);
    }

    private boolean shouldPrettyPrint(LogEvent event) {
        String contentType = event.getContentType(); 
        return prettyLogging 
            && contentType != null 
            && contentType.indexOf("xml") >= 0
            && contentType.toLowerCase().indexOf("multipart/related") < 0
            && event.getPayload().length() > 0;
    }

    /**
     * Pretty-print {@linkplain LogEvent} XML payload.
     * 
     * @param event the log event containing an XML payload which is to be pretty-printed.
     * @return pretty-printed XML or original payload in case of an unexpected exception.
     */
    
    private String getPrettyMessage(LogEvent event) {
        String payload = event.getPayload();
        StringWriter swriter = new StringWriter(estimatePrettySize(payload));
        
        XMLStreamWriter xwriter = new PrettyPrintXMLStreamWriter(StaxUtils.createXMLStreamWriter(swriter), 2);
        XMLStreamReader xreader = StaxUtils.createXMLStreamReader(new StringReader(payload));
        try {
            StaxUtils.copy(xreader, xwriter);
            xwriter.flush();
        } catch (XMLStreamException | WstxLazyException e) {
            if (!event.isTruncated()) {
                LOG.debug("Error while pretty printing cxf message, returning raw message.", e);
                return payload;
            } 
            
            // Expected behavior for truncated payloads - keep what is already written.
            // This might effectively result in additional truncation, 
            // as the truncated XML document might result in partially parsed XML nodes, 
            // for example an open start tag. As long as a truncated payload is not 
            // mistaken for a non-truncated payload, we're good.
            flush(xwriter);
            return swriter.toString();
        } finally {
            close(xwriter);
            close(xreader);
        } 
        return swriter.toString();
    }
    
    private void flush(XMLStreamWriter xwriter) {
        try {
            xwriter.flush();
        } catch (XMLStreamException xse2) {
            //ignore
        }
    }
    
    private void close(XMLStreamWriter xwriter) {
        try {
            xwriter.close();
        } catch (XMLStreamException xse2) {
            //ignore
        }
    }

    private void close(XMLStreamReader xreader) {
        try {
            xreader.close();
        } catch (XMLStreamException xse2) {
            //ignore
        }
    }

    private int estimatePrettySize(String payload) {
        return payload.length() * 2;
    }

    public void setNext(LogEventSender next) {
        this.next = next;
    }
    
    public void setPrettyLogging(boolean prettyLogging) {
        this.prettyLogging = prettyLogging;
    }

}