/*
 * 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.logging.log4j.server;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;

import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.LogEventListener;
import org.apache.logging.log4j.core.parser.ParseException;
import org.apache.logging.log4j.core.parser.TextLogEventParser;
import org.apache.logging.log4j.util.Strings;

/**
 * Reads and logs {@link LogEvent}s from an {@link InputStream}.
 */
public abstract class InputStreamLogEventBridge extends AbstractLogEventBridge<InputStream> {

    private final int bufferSize;

    private final Charset charset;

    private final String eventEndMarker;
    
    private final TextLogEventParser parser;
    
    public InputStreamLogEventBridge(final TextLogEventParser parser, final int bufferSize, final Charset charset, final String eventEndMarker) {
        this.bufferSize = bufferSize;
        this.charset = charset;
        this.eventEndMarker = eventEndMarker;
        this.parser = parser;
    }

    abstract protected int[] getEventIndices(final String text, int beginIndex);

    @Override
    public void logEvents(final InputStream inputStream, final LogEventListener logEventListener)
            throws IOException, ParseException {
        String workingText = Strings.EMPTY;
        try {
            // Allocate buffer once
            final byte[] buffer = new byte[bufferSize];
            String textRemains = workingText = Strings.EMPTY;
            while (true) {
                // Process until the stream is EOF.
                final int streamReadLength = inputStream.read(buffer);
                if (streamReadLength == END) {
                    // The input stream is EOF
                    break;
                }
                final String text = workingText = textRemains + new String(buffer, 0, streamReadLength, charset);
                int beginIndex = 0;
                while (true) {
                    // Extract and log all XML events in the buffer
                    final int[] pair = getEventIndices(text, beginIndex);
                    final int eventStartMarkerIndex = pair[0];
                    if (eventStartMarkerIndex < 0) {
                        // No more events or partial XML only in the buffer.
                        // Save the unprocessed string part
                        textRemains = text.substring(beginIndex);
                        break;
                    }
                    final int eventEndMarkerIndex = pair[1];
                    if (eventEndMarkerIndex > 0) {
                        final int eventEndXmlIndex = eventEndMarkerIndex + eventEndMarker.length();
                        final String textEvent = workingText = text.substring(eventStartMarkerIndex, eventEndXmlIndex);
                        final LogEvent logEvent = unmarshal(textEvent);
                        logEventListener.log(logEvent);
                        beginIndex = eventEndXmlIndex;
                    } else {
                        // No more events or partial XML only in the buffer.
                        // Save the unprocessed string part
                        textRemains = text.substring(beginIndex);
                        break;
                    }
                }
            }
        } catch (final IOException ex) {
            logger.error(workingText, ex);
        }
    }

    protected LogEvent unmarshal(final String jsonEvent) throws ParseException {
        return this.parser.parseFrom(jsonEvent);
    }

    @Override
    public String toString() {
        return getClass().getName() + " [bufferSize=" + bufferSize + ", charset=" + charset + ", eventEndMarker="
                + eventEndMarker + ", parser=" + parser + "]";
    }

}
