/*
 * 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 com.google.common.io.BaseEncoding;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.List;
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,
           BaseEncoding.base64().encode(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);

    }

}
