/*
 * 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.felix.shell.remote;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.io.Reader;

/**
 * Class implementing a terminal reader adapter
 * originally designed for the BeanShell Interpreter.
 * <p/>
 * Provides simple line editing (Backspace, Strg-U and a history).
 */
class TerminalReader extends Reader
{
    protected final InputStream m_in;
    protected final PrintStream m_out;
    protected boolean m_echo = false;
    protected boolean m_eof = false;

    public TerminalReader(InputStream in, PrintStream out)
    {
        m_in = in;
        m_out = out;
    }//TerminalReader

    /**
     * Tests if this <tt>TerminalReader</tt> will echo
     * the character input to the terminal.
     *
     * @return true if echo, false otherwise.
     */
    public boolean isEcho()
    {
        return m_echo;
    }//isEcho

    /**
     * Sets if this <tt>TerminalReader</tt> will echo
     * the character input to the terminal.
     * <p/>
     * This only makes sense in character input mode,
     * in line mode the terminal will handle editing,
     * and this is recommended for using a more complex shell.
     * If you implement your own character based editor, you
     * might as well change this.<br/>
     * (Default is false).
     *
     * @param echo true if echo, false otherwise.
     */
    public void setEcho(boolean echo)
    {
        m_echo = echo;
    }//setEcho

    public int read(char[] chars, int off, int len) throws IOException
    {
        if (m_eof)
        {
            return -1;
        }
        for (int i = off; i < off + len; i++)
        {
            int ch = m_in.read();
            //shortcut for EOT and simple EOF
            if (ch == EOT || (i == off && ch == -1))
            {
                return -1;
            }
            chars[i] = (char) ch;
            if (ch == -1 || ch == 10 || ch == 13)
            {
                m_eof = ch == -1; //store EOF
                int read = i - off + 1;
                if (m_echo)
                {
                    m_out.write(CRLF);
                }
                return read;
            }
            //naive backspace handling
            if (ch == BS || ch == DEL)
            {
                if (i > off)
                {
                    i = i - 2;
                    moveLeft(1);
                    eraseToEndOfLine();
                }
                else
                {
                    i--;
                    bell();
                }
            }
            else if (ch == CTRL_U)
            {
                moveLeft(i - off);
                eraseToEndOfLine();
                i = off - 1;
            }
            else
            {
                if (m_echo)
                {
                    m_out.write(chars[i]);
                }
            }
        }
        return len;
    }//read

    /**
     * Writes the NVT BEL character to the output.
     */
    private void bell()
    {
        m_out.write(BEL);
        m_out.flush();
    }//bell

    /**
     * Writes the standard vt100/ansi cursor moving code to the output.
     *
     * @param i the number of times the cursor should be moved left.
     * @throws IOException if I/O fails.
     */
    private void moveLeft(int i) throws IOException
    {
        CURSOR_LEFT[2] = Byte.decode(Integer.toString(i)).byteValue();
        m_out.write(CURSOR_LEFT);
        m_out.flush();
    }//moveLeft

    /**
     * Writes the standard vt100/ansi sequence for erasing to the end of the current line.
     *
     * @throws IOException if I/O fails.
     */
    private void eraseToEndOfLine() throws IOException
    {
        m_out.write(ERASE_TEOL);
        m_out.flush();
    }//eraseToEndOfLine

    /**
     * Closes this reader.
     * Note: will close the input, but not the output.
     *
     * @throws IOException
     */
    public void close() throws IOException
    {
        m_in.close();
    }//close

    /**
     * <b>Bell</b><br>
     * The ANSI defined byte code for the NVT bell.
     */
    public static final byte BEL = 7;
    /**
     * <b>BackSpace</b><br>
     * The ANSI defined byte code of backspace.
     */
    public static final byte BS = 8;
    /**
     * <b>Delete</b><br>
     * The ANSI defined byte code of delete.
     */
    public static final byte DEL = 127;
    /**
     * CTRL-u
     */
    public static final byte CTRL_U = 21;
    /**
     * Escape character.
     */
    private static byte ESC = 27;
    /**
     * vt100/ansi standard sequence for moving the cursor left.
     */
    private static byte[] CURSOR_LEFT =
    {
        ESC, '[', '1', 'D'
    };
    /**
     * vt100/ansi standard sequence for erasing everything from the actual cursor to
     * the end of the current line.
     */
    private static byte[] ERASE_TEOL =
    {
        ESC, '[', 'K'
    };
    /**
     * Standard NVT line break, which HAS TO BE CR and LF.
     */
    private static byte[] CRLF =
    {
        '\r', '\n'
    };
    /**
     * Standard ASCII end of transmission.
     */
    private static byte EOT = 4;
}//class TerminalReader
