/*
 * 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.guacamole.tunnel;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
import javax.xml.bind.DatatypeConverter;
import org.apache.guacamole.GuacamoleException;
import org.apache.guacamole.net.GuacamoleTunnel;
import org.apache.guacamole.protocol.GuacamoleInstruction;
import org.apache.guacamole.protocol.GuacamoleStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Filter which selectively intercepts "ack" instructions, automatically reading
 * from or closing the stream given with interceptStream(). The required "blob"
 * and "end" instructions denoting the content and boundary of the stream are
 * sent automatically.
 */
public class InputStreamInterceptingFilter
        extends StreamInterceptingFilter<InputStream> {

    /**
     * Logger for this class.
     */
    private static final Logger logger =
            LoggerFactory.getLogger(InputStreamInterceptingFilter.class);

    /**
     * Creates a new InputStreamInterceptingFilter which selectively intercepts
     * "ack" instructions. The required "blob" and "end" instructions will
     * automatically be sent over the given tunnel based on the content of
     * provided InputStreams.
     *
     * @param tunnel
     *     The GuacamoleTunnel over which any required "blob" and "end"
     *     instructions should be sent.
     */
    public InputStreamInterceptingFilter(GuacamoleTunnel tunnel) {
        super(tunnel);
    }

    /**
     * Injects a "blob" instruction into the outbound Guacamole protocol
     * stream, as if sent by the connected client. "blob" instructions are used
     * to send chunks of data along a stream.
     *
     * @param index
     *     The index of the stream that this "blob" instruction relates to.
     *
     * @param blob
     *     The chunk of data to send within the "blob" instruction.
     */
    private void sendBlob(String index, byte[] blob) {

        // Send "blob" containing provided data
        sendInstruction(new GuacamoleInstruction("blob", index,
            DatatypeConverter.printBase64Binary(blob)));

    }

    /**
     * Injects an "end" instruction into the outbound Guacamole protocol
     * stream, as if sent by the connected client. "end" instructions are used
     * to signal the end of a stream.
     *
     * @param index
     *     The index of the stream that this "end" instruction relates to.
     */
    private void sendEnd(String index) {
        sendInstruction(new GuacamoleInstruction("end", index));
    }

    /**
     * Reads the next chunk of data from the InputStream associated with an
     * intercepted stream, sending that data as a "blob" instruction over the
     * GuacamoleTunnel associated with this filter. If the end of the
     * InputStream is reached, an "end" instruction will automatically be sent.
     *
     * @param stream
     *     The stream from which the next chunk of data should be read.
     */
    private void readNextBlob(InterceptedStream<InputStream> stream) {

        // Read blob from stream if it exists
        try {

            // Read raw data from input stream
            byte[] blob = new byte[6048];
            int length = stream.getStream().read(blob);

            // End stream if no more data
            if (length == -1) {

                // Close stream, send end if the stream is still valid
                if (closeInterceptedStream(stream))
                    sendEnd(stream.getIndex());

                return;

            }

            // Inject corresponding "blob" instruction
            sendBlob(stream.getIndex(), Arrays.copyOf(blob, length));

        }

        // Terminate stream if it cannot be read
        catch (IOException e) {

            logger.debug("Unable to read data of intercepted input stream.", e);

            // Close stream, send end if the stream is still valid
            if (closeInterceptedStream(stream))
                sendEnd(stream.getIndex());

        }

    }

    /**
     * Handles a single "ack" instruction, sending yet more blobs or closing the
     * stream depending on whether the "ack" indicates success or failure. If no
     * InputStream is associated with the stream index within the "ack"
     * instruction, the instruction is ignored.
     *
     * @param instruction
     *     The "ack" instruction being handled.
     */
    private void handleAck(GuacamoleInstruction instruction) {

        // Verify all required arguments are present
        List<String> args = instruction.getArgs();
        if (args.size() < 3)
            return;

        // Pull associated stream
        String index = args.get(0);
        InterceptedStream<InputStream> stream = getInterceptedStream(index);
        if (stream == null)
            return;

        // Pull status code
        String status = args.get(2);

        // Terminate stream if an error is encountered
        if (!status.equals("0")) {

            // Parse status code as integer
            int code;
            try {
                code = Integer.parseInt(status);
            }

            // Assume internal error if parsing fails
            catch (NumberFormatException e) {
                logger.debug("Translating invalid status code \"{}\" to SERVER_ERROR.", status);
                code = GuacamoleStatus.SERVER_ERROR.getGuacamoleStatusCode();
            }

            // Flag error and close stream
            stream.setStreamError(code, args.get(1));
            closeInterceptedStream(stream);
            return;

        }

        // Send next blob
        readNextBlob(stream);

    }

    @Override
    public GuacamoleInstruction filter(GuacamoleInstruction instruction)
            throws GuacamoleException {

        // Intercept "ack" instructions for in-progress streams
        if (instruction.getOpcode().equals("ack"))
            handleAck(instruction);

        // Pass instruction through untouched
        return instruction;

    }

    @Override
    protected void handleInterceptedStream(InterceptedStream<InputStream> stream) {

        // Read the first blob. Note that future blobs will be read in response
        // to received "ack" instructions.
        readNextBlob(stream);

    }

}
