// Copyright 2016 Joe Wilm, The Alacritty Project Contributors
//
// Licensed 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.
//
//! ANSI Terminal Stream Parsing
use std::io;
use std::ops::Range;
use std::str;

use vte;

use index::{Column, Line, Contains};

use ::Rgb;

/// The processor wraps a `vte::Parser` to ultimately call methods on a Handler
pub struct Processor {
    state: ProcessorState,
    parser: vte::Parser,
}

/// Internal state for VTE processor
struct ProcessorState;

/// Helper type that implements `vte::Perform`.
///
/// Processor creates a Performer when running advance and passes the Performer
/// to `vte::Parser`.
struct Performer<'a, H: Handler + TermInfo + 'a, W: io::Write + 'a> {
    _state: &'a mut ProcessorState,
    handler: &'a mut H,
    writer: &'a mut W
}

impl<'a, H: Handler + TermInfo + 'a, W: io::Write> Performer<'a, H, W> {
    /// Create a performer
    #[inline]
    pub fn new<'b>(
        state: &'b mut ProcessorState,
        handler: &'b mut H,
        writer: &'b mut W,
    ) -> Performer<'b, H, W> {
        Performer {
            _state: state,
            handler: handler,
            writer: writer,
        }
    }
}

impl Default for Processor {
    fn default() -> Processor {
        Processor {
            state: ProcessorState,
            parser: vte::Parser::new(),
        }
    }
}

impl Processor {
    pub fn new() -> Processor {
        Default::default()
    }

    #[inline]
    pub fn advance<H, W>(
        &mut self,
        handler: &mut H,
        byte: u8,
        writer: &mut W
    )
        where H: Handler + TermInfo,
              W: io::Write
    {
        let mut performer = Performer::new(&mut self.state, handler, writer);
        self.parser.advance(&mut performer, byte);
    }
}


/// Trait that provides properties of terminal
pub trait TermInfo {
    fn lines(&self) -> Line;
    fn cols(&self) -> Column;
}

/// Type that handles actions from the parser
///
/// XXX Should probably not provide default impls for everything, but it makes
/// writing specific handler impls for tests far easier.
pub trait Handler {
    /// OSC to set window title
    fn set_title(&mut self, &str) {}

    /// Set the cursor style
    fn set_cursor_style(&mut self, _: CursorStyle) {}

    /// A character to be displayed
    fn input(&mut self, _c: char) {}

    /// Set cursor to position
    fn goto(&mut self, Line, Column) {}

    /// Set cursor to specific row
    fn goto_line(&mut self, Line) {}

    /// Set cursor to specific column
    fn goto_col(&mut self, Column) {}

    /// Insert blank characters in current line starting from cursor
    fn insert_blank(&mut self, Column) {}

    /// Move cursor up `rows`
    fn move_up(&mut self, Line) {}

    /// Move cursor down `rows`
    fn move_down(&mut self, Line) {}

    /// Identify the terminal (should write back to the pty stream)
    ///
    /// TODO this should probably return an io::Result
    fn identify_terminal<W: io::Write>(&mut self, &mut W) {}

    // Report device status
    fn device_status<W: io::Write>(&mut self, &mut W, usize) {}

    /// Move cursor forward `cols`
    fn move_forward(&mut self, Column) {}

    /// Move cursor backward `cols`
    fn move_backward(&mut self, Column) {}

    /// Move cursor down `rows` and set to column 1
    fn move_down_and_cr(&mut self, Line) {}

    /// Move cursor up `rows` and set to column 1
    fn move_up_and_cr(&mut self, Line) {}

    /// Put `count` tabs
    fn put_tab(&mut self, _count: i64) {}

    /// Backspace `count` characters
    fn backspace(&mut self) {}

    /// Carriage return
    fn carriage_return(&mut self) {}

    /// Linefeed
    fn linefeed(&mut self) {}

    /// Ring the bell
    ///
    /// Hopefully this is never implemented
    fn bell(&mut self) {}

    /// Substitute char under cursor
    fn substitute(&mut self) {}

    /// Newline
    fn newline(&mut self) {}

    /// Set current position as a tabstop
    fn set_horizontal_tabstop(&mut self) {}

    /// Scroll up `rows` rows
    fn scroll_up(&mut self, Line) {}

    /// Scroll down `rows` rows
    fn scroll_down(&mut self, Line) {}

    /// Insert `count` blank lines
    fn insert_blank_lines(&mut self, Line) {}

    /// Delete `count` lines
    fn delete_lines(&mut self, Line) {}

    /// Erase `count` chars in current line following cursor
    ///
    /// Erase means resetting to the default state (default colors, no content,
    /// no mode flags)
    fn erase_chars(&mut self, Column) {}

    /// Delete `count` chars
    ///
    /// Deleting a character is like the delete key on the keyboard - everything
    /// to the right of the deleted things is shifted left.
    fn delete_chars(&mut self, Column) {}

    /// Move backward `count` tabs
    fn move_backward_tabs(&mut self, _count: i64) {}

    /// Move forward `count` tabs
    fn move_forward_tabs(&mut self, _count: i64) {}

    /// Save current cursor position
    fn save_cursor_position(&mut self) {}

    /// Restore cursor position
    fn restore_cursor_position(&mut self) {}

    /// Clear current line
    fn clear_line(&mut self, _mode: LineClearMode) {}

    /// Clear screen
    fn clear_screen(&mut self, _mode: ClearMode) {}

    /// Clear tab stops
    fn clear_tabs(&mut self, _mode: TabulationClearMode) {}

    /// Reset terminal state
    fn reset_state(&mut self) {}

    /// Reverse Index
    ///
    /// Move the active position to the same horizontal position on the
    /// preceding line. If the active position is at the top margin, a scroll
    /// down is performed
    fn reverse_index(&mut self) {}

    /// set a terminal attribute
    fn terminal_attribute(&mut self, _attr: Attr) {}

    /// Set mode
    fn set_mode(&mut self, _mode: Mode) {}

    /// Unset mode
    fn unset_mode(&mut self, Mode) {}

    /// DECSTBM - Set the terminal scrolling region
    fn set_scrolling_region(&mut self, Range<Line>) {}

    /// DECKPAM - Set keypad to applications mode (ESCape instead of digits)
    fn set_keypad_application_mode(&mut self) {}

    /// DECKPNM - Set keypad to numeric mode (digits intead of ESCape seq)
    fn unset_keypad_application_mode(&mut self) {}

    /// Set one of the graphic character sets, G0 to G3, as the active charset.
    ///
    /// 'Invoke' one of G0 to G3 in the GL area. Also refered to as shift in,
    /// shift out and locking shift depending on the set being activated
    fn set_active_charset(&mut self, CharsetIndex) {}

    /// Assign a graphic character set to G0, G1, G2 or G3
    ///
    /// 'Designate' a graphic character set as one of G0 to G3, so that it can
    /// later be 'invoked' by `set_active_charset`
    fn configure_charset(&mut self, CharsetIndex, StandardCharset) {}

    /// Set an indexed color value
    fn set_color(&mut self, usize, Rgb) {}

    /// Run the dectest routine
    fn dectest(&mut self) {}
}

/// Describes shape of cursor
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
pub enum CursorStyle {
    /// Cursor is a block like `▒`
    Block,

    /// Cursor is an underscore like `_`
    Underline,

    /// Cursor is a vertical bar `⎸`
    Beam,
}

/// Terminal modes
#[derive(Debug, Eq, PartialEq)]
pub enum Mode {
    /// ?1
    CursorKeys = 1,
    /// Select 80 or 132 columns per page
    ///
    /// CSI ? 3 h -> set 132 column font
    /// CSI ? 3 l -> reset 80 column font
    ///
    /// Additionally,
    ///
    /// * set margins to default positions
    /// * erases all data in page memory
    /// * resets DECLRMM to unavailable
    /// * clears data from the status line (if set to host-writable)
    DECCOLM = 3,
    /// IRM Insert Mode
    ///
    /// NB should be part of non-private mode enum
    ///
    /// * `CSI 4 h` change to insert mode
    /// * `CSI 4 l` reset to replacement mode
    Insert = 4,
    /// ?6
    Origin = 6,
    /// ?7
    LineWrap = 7,
    /// ?12
    BlinkingCursor = 12,
    /// 20
    ///
    /// NB This is actually a private mode. We should consider adding a second
    /// enumeration for public/private modesets.
    LineFeedNewLine = 20,
    /// ?25
    ShowCursor = 25,
    /// ?1000
    ReportMouseClicks = 1000,
    /// ?1002
    ReportMouseMotion = 1002,
    /// ?1004
    ReportFocusInOut = 1004,
    /// ?1006
    SgrMouse = 1006,
    /// ?1049
    SwapScreenAndSetRestoreCursor = 1049,
    /// ?2004
    BracketedPaste = 2004,
}

impl Mode {
    /// Create mode from a primitive
    ///
    /// TODO lots of unhandled values..
    pub fn from_primitive(private: bool, num: i64) -> Option<Mode> {
        if private {
            Some(match num {
                1 => Mode::CursorKeys,
                3 => Mode::DECCOLM,
                6 => Mode::Origin,
                7 => Mode::LineWrap,
                12 => Mode::BlinkingCursor,
                25 => Mode::ShowCursor,
                1000 => Mode::ReportMouseClicks,
                1002 => Mode::ReportMouseMotion,
                1004 => Mode::ReportFocusInOut,
                1006 => Mode::SgrMouse,
                1049 => Mode::SwapScreenAndSetRestoreCursor,
                2004 => Mode::BracketedPaste,
                _ => return None
            })
        } else {
            Some(match num {
                4 => Mode::Insert,
                20 => Mode::LineFeedNewLine,
                _ => return None
            })
        }
    }
}

/// Mode for clearing line
///
/// Relative to cursor
#[derive(Debug)]
pub enum LineClearMode {
    /// Clear right of cursor
    Right,
    /// Clear left of cursor
    Left,
    /// Clear entire line
    All,
}

/// Mode for clearing terminal
///
/// Relative to cursor
#[derive(Debug)]
pub enum ClearMode {
    /// Clear below cursor
    Below,
    /// Clear above cursor
    Above,
    /// Clear entire terminal
    All,
    /// Clear 'saved' lines (scrollback)
    Saved
}

/// Mode for clearing tab stops
#[derive(Debug)]
pub enum TabulationClearMode {
    /// Clear stop under cursor
    Current,
    /// Clear all stops
    All,
}

/// Standard colors
///
/// The order here matters since the enum should be castable to a `usize` for
/// indexing a color list.
#[derive(Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
pub enum NamedColor {
    /// Black
    Black = 0,
    /// Red
    Red,
    /// Green
    Green,
    /// Yellow
    Yellow,
    /// Blue
    Blue,
    /// Magenta
    Magenta,
    /// Cyan
    Cyan,
    /// White
    White,
    /// Bright black
    BrightBlack,
    /// Bright red
    BrightRed,
    /// Bright green
    BrightGreen,
    /// Bright yellow
    BrightYellow,
    /// Bright blue
    BrightBlue,
    /// Bright magenta
    BrightMagenta,
    /// Bright cyan
    BrightCyan,
    /// Bright white
    BrightWhite,
    /// The foreground color
    Foreground = 256,
    /// The background color
    Background,
    /// Color for the text under the cursor
    CursorText,
    /// Color for the cursor itself
    Cursor,
    /// Dim black
    DimBlack,
    /// Dim red
    DimRed,
    /// Dim green
    DimGreen,
    /// Dim yellow
    DimYellow,
    /// Dim blue
    DimBlue,
    /// Dim magenta
    DimMagenta,
    /// Dim cyan
    DimCyan,
    /// Dim white
    DimWhite,
}

impl NamedColor {
    pub fn to_bright(&self) -> Self {
        match *self {
            NamedColor::Black => NamedColor::BrightBlack,
            NamedColor::Red => NamedColor::BrightRed,
            NamedColor::Green => NamedColor::BrightGreen,
            NamedColor::Yellow => NamedColor::BrightYellow,
            NamedColor::Blue => NamedColor::BrightBlue,
            NamedColor::Magenta => NamedColor::BrightMagenta,
            NamedColor::Cyan => NamedColor::BrightCyan,
            NamedColor::White => NamedColor::BrightWhite,
            NamedColor::DimBlack => NamedColor::Black,
            NamedColor::DimRed => NamedColor::Red,
            NamedColor::DimGreen => NamedColor::Green,
            NamedColor::DimYellow => NamedColor::Yellow,
            NamedColor::DimBlue => NamedColor::Blue,
            NamedColor::DimMagenta => NamedColor::Magenta,
            NamedColor::DimCyan => NamedColor::Cyan,
            NamedColor::DimWhite => NamedColor::White,
            val => val
        }
    }

    pub fn to_dim(&self) -> Self {
        match *self {
            NamedColor::Black => NamedColor::DimBlack,
            NamedColor::Red => NamedColor::DimRed,
            NamedColor::Green => NamedColor::DimGreen,
            NamedColor::Yellow => NamedColor::DimYellow,
            NamedColor::Blue => NamedColor::DimBlue,
            NamedColor::Magenta => NamedColor::DimMagenta,
            NamedColor::Cyan => NamedColor::DimCyan,
            NamedColor::White => NamedColor::DimWhite,
            NamedColor::BrightBlack => NamedColor::Black,
            NamedColor::BrightRed => NamedColor::Red,
            NamedColor::BrightGreen => NamedColor::Green,
            NamedColor::BrightYellow => NamedColor::Yellow,
            NamedColor::BrightBlue => NamedColor::Blue,
            NamedColor::BrightMagenta => NamedColor::Magenta,
            NamedColor::BrightCyan => NamedColor::Cyan,
            NamedColor::BrightWhite => NamedColor::White,
            val => val
        }
    }
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum Color {
    Named(NamedColor),
    Spec(Rgb),
    Indexed(u8),
}

/// Terminal character attributes
#[derive(Debug, Eq, PartialEq)]
pub enum Attr {
    /// Clear all special abilities
    Reset,
    /// Bold text
    Bold,
    /// Dim or secondary color
    Dim,
    /// Italic text
    Italic,
    /// Underscore text
    Underscore,
    /// Blink cursor slowly
    BlinkSlow,
    /// Blink cursor fast
    BlinkFast,
    /// Invert colors
    Reverse,
    /// Do not display characters
    Hidden,
    /// Strikethrough text
    Strike,
    /// Cancel bold and dim
    CancelBoldDim,
    /// Cancel italic
    CancelItalic,
    /// Cancel underline
    CancelUnderline,
    /// Cancel blink
    CancelBlink,
    /// Cancel inversion
    CancelReverse,
    /// Cancel text hiding
    CancelHidden,
    /// Cancel strike through
    CancelStrike,
    /// Set indexed foreground color
    Foreground(Color),
    /// Set indexed background color
    Background(Color),
}

/// Identifiers which can be assigned to a graphic character set
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum CharsetIndex {
    /// Default set, is designated as ASCII at startup
    G0,
    G1,
    G2,
    G3,
}

impl Default for CharsetIndex {
    fn default() -> Self {
        CharsetIndex::G0
    }
}

/// Standard or common character sets which can be designated as G0-G3
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum StandardCharset {
    Ascii,
    SpecialCharacterAndLineDrawing,
}

impl Default for StandardCharset {
    fn default() -> Self {
        StandardCharset::Ascii
    }
}

impl<'a, H, W> vte::Perform for Performer<'a, H, W>
    where H: Handler + TermInfo + 'a,
          W: io::Write + 'a
{
    #[inline]
    fn print(&mut self, c: char) {
        self.handler.input(c);
    }

    #[inline]
    fn execute(&mut self, byte: u8) {
        match byte {
            C0::HT => self.handler.put_tab(1),
            C0::BS => self.handler.backspace(),
            C0::CR => self.handler.carriage_return(),
            C0::LF | C0::VT | C0::FF => self.handler.linefeed(),
            C0::BEL => self.handler.bell(),
            C0::SUB => self.handler.substitute(),
            C0::SI => self.handler.set_active_charset(CharsetIndex::G0),
            C0::SO => self.handler.set_active_charset(CharsetIndex::G1),
            C1::NEL => self.handler.newline(),
            C1::HTS => self.handler.set_horizontal_tabstop(),
            C1::DECID => self.handler.identify_terminal(self.writer),
            _ => debug!("[unhandled] execute byte={:02x}", byte)
        }
    }

    #[inline]
    fn hook(&mut self, params: &[i64], intermediates: &[u8], ignore: bool) {
        debug!("[unhandled hook] params={:?}, ints: {:?}, ignore: {:?}",
                     params, intermediates, ignore);
    }

    #[inline]
    fn put(&mut self, byte: u8) {
        debug!("[unhandled put] byte={:?}", byte);
    }

    #[inline]
    fn unhook(&mut self) {
        debug!("[unhandled unhook]");
    }

    // TODO replace OSC parsing with parser combinators
    #[inline]
    fn osc_dispatch(&mut self, params: &[&[u8]]) {
        macro_rules! unhandled {
            () => {{
                let mut buf = String::new();
                for items in params {
                    buf.push_str("[");
                    for item in *items {
                        buf.push_str(&format!("{:?},", *item as char));
                    }
                    buf.push_str("],");
                }
                warn!("[unhandled osc_dispatch]: [{}] at line {}", &buf, line!());
            }}
        }

        if params.is_empty() || params[0].is_empty() {
            return;
        }

        match params[0][0] {
            // Set window title
            b'0' | b'2' => {
                if params.len() < 2 {
                    return unhandled!();
                }

                if let Ok(utf8_title) = str::from_utf8(params[1]) {
                    self.handler.set_title(utf8_title);
                }
            },

            // Set icon name
            // This is ignored, since alacritty has no concept of tabs
            b'1' => return,

            // Set color index
            b'4' => {
                if params.len() < 3 {
                    return unhandled!();
                }

                // Parse index
                let index = {
                    let raw = params[1];
                    if raw.len() > 3 {
                        return unhandled!();
                    }
                    let mut index: u8 = 0;
                    for c in raw {
                        let c = *c as char;
                        if let Some(digit) = c.to_digit(10) {
                            index *= 10;
                            index += digit as u8;
                        }
                    }

                    index
                };

                // Check that index is a valid u8
                if index & 0xff != index {
                    return unhandled!();
                }

                // Parse color arguments
                //
                // Expect that color argument looks like "rgb:xx/xx/xx"
                let color = {
                    let raw = params[2];
                    let mut iter = raw.iter();
                    macro_rules! next {
                        () => {
                            iter.next().map(|v| *v as char)
                        }
                    }
                    if next!() != Some('r') { return unhandled!(); }
                    if next!() != Some('g') { return unhandled!(); }
                    if next!() != Some('b') { return unhandled!(); }
                    if next!() != Some(':') { return unhandled!(); }

                    macro_rules! parse_hex {
                        () => {{
                            let mut digit: u8 = 0;
                            let next = next!().and_then(|v| v.to_digit(16));
                            if let Some(value) = next {
                                digit = value as u8;
                            }

                            let next = next!().and_then(|v| v.to_digit(16));
                            if let Some(value) = next {
                                digit <<= 4;
                                digit += value as u8;
                            }
                            digit
                        }}
                    }

                    let r = parse_hex!();
                    let val = next!();
                    if val != Some('/') { println!("val={:?}", val); return unhandled!(); }
                    let g = parse_hex!();
                    if next!() != Some('/') { return unhandled!(); }
                    let b = parse_hex!();

                    Rgb { r: r, g: g, b: b}
                };

                self.handler.set_color(index as usize, color);
            }
            _ => {
                unhandled!();
            }
        }
    }

    #[inline]
    fn csi_dispatch(
        &mut self,
        args: &[i64],
        intermediates: &[u8],
        _ignore: bool,
        action: char
    ) {
        let private = intermediates.get(0).map(|b| *b == b'?').unwrap_or(false);
        let handler = &mut self.handler;
        let writer = &mut self.writer;


        macro_rules! unhandled {
            () => {{
                warn!("[Unhandled CSI] action={:?}, args={:?}, intermediates={:?}",
                             action, args, intermediates);
                return;
            }}
        }

        macro_rules! arg_or_default {
            (idx: $idx:expr, default: $default:expr) => {
                args.get($idx).and_then(|v| {
                    if *v == 0 {
                        None
                    } else {
                        Some(*v)
                    }
                }).unwrap_or($default)
            }
        }

        match action {
            '@' => handler.insert_blank(Column(arg_or_default!(idx: 0, default: 1) as usize)),
            'A' => {
                handler.move_up(Line(arg_or_default!(idx: 0, default: 1) as usize));
            },
            'B' | 'e' => handler.move_down(Line(arg_or_default!(idx: 0, default: 1) as usize)),
            'c' => handler.identify_terminal(writer),
            'C' | 'a' => handler.move_forward(Column(arg_or_default!(idx: 0, default: 1) as usize)),
            'D' => handler.move_backward(Column(arg_or_default!(idx: 0, default: 1) as usize)),
            'E' => handler.move_down_and_cr(Line(arg_or_default!(idx: 0, default: 1) as usize)),
            'F' => handler.move_up_and_cr(Line(arg_or_default!(idx: 0, default: 1) as usize)),
            'g' => {
                let mode = match arg_or_default!(idx: 0, default: 0) {
                    0 => TabulationClearMode::Current,
                    3 => TabulationClearMode::All,
                    _ => unhandled!(),
                };

                handler.clear_tabs(mode);
            },
            'G' | '`' => handler.goto_col(Column(arg_or_default!(idx: 0, default: 1) as usize - 1)),
            'H' | 'f' => {
                let y = arg_or_default!(idx: 0, default: 1) as usize;
                let x = arg_or_default!(idx: 1, default: 1) as usize;
                handler.goto(Line(y - 1), Column(x - 1));
            },
            'I' => handler.move_forward_tabs(arg_or_default!(idx: 0, default: 1)),
            'J' => {
                let mode = match arg_or_default!(idx: 0, default: 0) {
                    0 => ClearMode::Below,
                    1 => ClearMode::Above,
                    2 => ClearMode::All,
                    3 => ClearMode::Saved,
                    _ => unhandled!(),
                };

                handler.clear_screen(mode);
            },
            'K' => {
                let mode = match arg_or_default!(idx: 0, default: 0) {
                    0 => LineClearMode::Right,
                    1 => LineClearMode::Left,
                    2 => LineClearMode::All,
                    _ => unhandled!(),
                };

                handler.clear_line(mode);
            },
            'S' => handler.scroll_up(Line(arg_or_default!(idx: 0, default: 1) as usize)),
            'T' => handler.scroll_down(Line(arg_or_default!(idx: 0, default: 1) as usize)),
            'L' => handler.insert_blank_lines(Line(arg_or_default!(idx: 0, default: 1) as usize)),
            'l' => {
                let mode = Mode::from_primitive(private, arg_or_default!(idx: 0, default: 0));
                match mode {
                    Some(mode) => handler.unset_mode(mode),
                    None => unhandled!(),
                }
            },
            'M' => handler.delete_lines(Line(arg_or_default!(idx: 0, default: 1) as usize)),
            'X' => handler.erase_chars(Column(arg_or_default!(idx: 0, default: 1) as usize)),
            'P' => handler.delete_chars(Column(arg_or_default!(idx: 0, default: 1) as usize)),
            'Z' => handler.move_backward_tabs(arg_or_default!(idx: 0, default: 1)),
            'd' => handler.goto_line(Line(arg_or_default!(idx: 0, default: 1) as usize - 1)),
            'h' => {
                let mode = Mode::from_primitive(private, arg_or_default!(idx: 0, default: 0));
                match mode {
                    Some(mode) => handler.set_mode(mode),
                    None => unhandled!(),
                }
            },
            'm' => {
                // Sometimes a C-style for loop is just what you need
                let mut i = 0; // C-for initializer
                if args.len() == 0 {
                    handler.terminal_attribute(Attr::Reset);
                    return;
                }
                loop {
                    // println!("args.len = {}; i={}", args.len(), i);
                    if i >= args.len() { // C-for condition
                        break;
                    }

                    let attr = match args[i] {
                        0 => Attr::Reset,
                        1 => Attr::Bold,
                        2 => Attr::Dim,
                        3 => Attr::Italic,
                        4 => Attr::Underscore,
                        5 => Attr::BlinkSlow,
                        6 => Attr::BlinkFast,
                        7 => Attr::Reverse,
                        8 => Attr::Hidden,
                        9 => Attr::Strike,
                        22 => Attr::CancelBoldDim,
                        23 => Attr::CancelItalic,
                        24 => Attr::CancelUnderline,
                        25 => Attr::CancelBlink,
                        27 => Attr::CancelReverse,
                        28 => Attr::CancelHidden,
                        29 => Attr::CancelStrike,
                        30 => Attr::Foreground(Color::Named(NamedColor::Black)),
                        31 => Attr::Foreground(Color::Named(NamedColor::Red)),
                        32 => Attr::Foreground(Color::Named(NamedColor::Green)),
                        33 => Attr::Foreground(Color::Named(NamedColor::Yellow)),
                        34 => Attr::Foreground(Color::Named(NamedColor::Blue)),
                        35 => Attr::Foreground(Color::Named(NamedColor::Magenta)),
                        36 => Attr::Foreground(Color::Named(NamedColor::Cyan)),
                        37 => Attr::Foreground(Color::Named(NamedColor::White)),
                        38 => {
                            let mut start = 0;
                            if let Some(color) = parse_color(&args[i..], &mut start) {
                                i += start;
                                Attr::Foreground(color)
                            } else {
                                break;
                            }
                        },
                        39 => Attr::Foreground(Color::Named(NamedColor::Foreground)),
                        40 => Attr::Background(Color::Named(NamedColor::Black)),
                        41 => Attr::Background(Color::Named(NamedColor::Red)),
                        42 => Attr::Background(Color::Named(NamedColor::Green)),
                        43 => Attr::Background(Color::Named(NamedColor::Yellow)),
                        44 => Attr::Background(Color::Named(NamedColor::Blue)),
                        45 => Attr::Background(Color::Named(NamedColor::Magenta)),
                        46 => Attr::Background(Color::Named(NamedColor::Cyan)),
                        47 => Attr::Background(Color::Named(NamedColor::White)),
                        48 =>  {
                            let mut start = 0;
                            if let Some(color) = parse_color(&args[i..], &mut start) {
                                i += start;
                                Attr::Background(color)
                            } else {
                                break;
                            }
                        },
                        49 => Attr::Background(Color::Named(NamedColor::Background)),
                        90 => Attr::Foreground(Color::Named(NamedColor::BrightBlack)),
                        91 => Attr::Foreground(Color::Named(NamedColor::BrightRed)),
                        92 => Attr::Foreground(Color::Named(NamedColor::BrightGreen)),
                        93 => Attr::Foreground(Color::Named(NamedColor::BrightYellow)),
                        94 => Attr::Foreground(Color::Named(NamedColor::BrightBlue)),
                        95 => Attr::Foreground(Color::Named(NamedColor::BrightMagenta)),
                        96 => Attr::Foreground(Color::Named(NamedColor::BrightCyan)),
                        97 => Attr::Foreground(Color::Named(NamedColor::BrightWhite)),
                        100 => Attr::Background(Color::Named(NamedColor::BrightBlack)),
                        101 => Attr::Background(Color::Named(NamedColor::BrightRed)),
                        102 => Attr::Background(Color::Named(NamedColor::BrightGreen)),
                        103 => Attr::Background(Color::Named(NamedColor::BrightYellow)),
                        104 => Attr::Background(Color::Named(NamedColor::BrightBlue)),
                        105 => Attr::Background(Color::Named(NamedColor::BrightMagenta)),
                        106 => Attr::Background(Color::Named(NamedColor::BrightCyan)),
                        107 => Attr::Background(Color::Named(NamedColor::BrightWhite)),
                        _ => unhandled!(),
                    };

                    handler.terminal_attribute(attr);

                    i += 1; // C-for expr
                }
            }
            'n' => handler.device_status(writer, arg_or_default!(idx: 0, default: 0) as usize),
            'r' => {
                if private {
                    unhandled!();
                }
                let arg0 = arg_or_default!(idx: 0, default: 1) as usize;
                let top = Line(arg0 - 1);
                // Bottom should be included in the range, but range end is not
                // usually included.  One option would be to use an inclusive
                // range, but instead we just let the open range end be 1
                // higher.
                let arg1 = arg_or_default!(idx: 1, default: handler.lines().0 as _) as usize;
                let bottom = Line(arg1);

                handler.set_scrolling_region(top..bottom);
            },
            's' => handler.save_cursor_position(),
            'u' => handler.restore_cursor_position(),
            'q' => {
                let style = match arg_or_default!(idx: 0, default: 0) {
                    0 ... 2 => CursorStyle::Block,
                    3 | 4 => CursorStyle::Underline,
                    5 | 6 => CursorStyle::Beam,
                    _ => unhandled!()
                };

                handler.set_cursor_style(style);
            }
            _ => unhandled!(),
        }
    }

    #[inline]
    fn esc_dispatch(
        &mut self,
        params: &[i64],
        intermediates: &[u8],
        _ignore: bool,
        byte: u8
    ) {
        macro_rules! unhandled {
            () => {{
                warn!("[unhandled] esc_dispatch params={:?}, ints={:?}, byte={:?} ({:02x})",
                             params, intermediates, byte as char, byte);
                return;
            }}
        }

        macro_rules! configure_charset {
            ($charset:path) => {{
                let index: CharsetIndex = match intermediates.first().cloned() {
                    Some(b'(') => CharsetIndex::G0,
                    Some(b')') => CharsetIndex::G1,
                    Some(b'*') => CharsetIndex::G2,
                    Some(b'+') => CharsetIndex::G3,
                    _ => unhandled!(),
                };
                self.handler.configure_charset(index, $charset)
            }}
        }

        match byte {
            b'B' => configure_charset!(StandardCharset::Ascii),
            b'D' => self.handler.linefeed(),
            b'E' => {
                self.handler.linefeed();
                self.handler.carriage_return();
            }
            b'H' => self.handler.set_horizontal_tabstop(),
            b'M' => self.handler.reverse_index(),
            b'Z' => self.handler.identify_terminal(self.writer),
            b'c' => self.handler.reset_state(),
            b'0' => configure_charset!(StandardCharset::SpecialCharacterAndLineDrawing),
            b'7' => self.handler.save_cursor_position(),
            b'8' => {
                if !intermediates.is_empty() && intermediates[0] == b'#' {
                    self.handler.dectest();
                } else {
                    self.handler.restore_cursor_position();
                }
            }
            b'=' => self.handler.set_keypad_application_mode(),
            b'>' => self.handler.unset_keypad_application_mode(),
            b'\\' => (), // String terminator, do nothing (parser handles as string terminator)
            _ => unhandled!(),
        }
    }
}


/// Parse a color specifier from list of attributes
fn parse_color(attrs: &[i64], i: &mut usize) -> Option<Color> {
    if attrs.len() < 2 {
        return None;
    }

    match attrs[*i+1] {
        2 => {
            // RGB color spec
            if attrs.len() < 5 {
                warn!("Expected RGB color spec; got {:?}", attrs);
                return None;
            }

            let r = attrs[*i+2];
            let g = attrs[*i+3];
            let b = attrs[*i+4];

            *i += 4;

            let range = 0..256;
            if !range.contains_(r) || !range.contains_(g) || !range.contains_(b) {
                warn!("Invalid RGB color spec: ({}, {}, {})", r, g, b);
                return None;
            }

            Some(Color::Spec(Rgb {
                r: r as u8,
                g: g as u8,
                b: b as u8
            }))
        },
        5 => {
            if attrs.len() < 3 {
                warn!("Expected color index; got {:?}", attrs);
                None
            } else {
                *i += 2;
                let idx = attrs[*i];
                match idx {
                    0 ... 255 => {
                        Some(Color::Indexed(idx as u8))
                    },
                    _ => {
                        warn!("Invalid color index: {}", idx);
                        None
                    }
                }
            }
        },
        _ => {
            warn!("Unexpected color attr: {}", attrs[*i+1]);
            None
        }
    }
}

/// C0 set of 7-bit control characters (from ANSI X3.4-1977).
#[allow(non_snake_case)]
pub mod C0 {
    /// Null filler, terminal should ignore this character
    pub const NUL: u8 = 0x00;
    /// Start of Header
    pub const SOH: u8 = 0x01;
    /// Start of Text, implied end of header
    pub const STX: u8 = 0x02;
    /// End of Text, causes some terminal to respond with ACK or NAK
    pub const ETX: u8 = 0x03;
    /// End of Transmission
    pub const EOT: u8 = 0x04;
    /// Enquiry, causes terminal to send ANSWER-BACK ID
    pub const ENQ: u8 = 0x05;
    /// Acknowledge, usually sent by terminal in response to ETX
    pub const ACK: u8 = 0x06;
    /// Bell, triggers the bell, buzzer, or beeper on the terminal
    pub const BEL: u8 = 0x07;
    /// Backspace, can be used to define overstruck characters
    pub const BS: u8 = 0x08;
    /// Horizontal Tabulation, move to next predetermined position
    pub const HT: u8 = 0x09;
    /// Linefeed, move to same position on next line (see also NL)
    pub const LF: u8 = 0x0A;
    /// Vertical Tabulation, move to next predetermined line
    pub const VT: u8 = 0x0B;
    /// Form Feed, move to next form or page
    pub const FF: u8 = 0x0C;
    /// Carriage Return, move to first character of current line
    pub const CR: u8 = 0x0D;
    /// Shift Out, switch to G1 (other half of character set)
    pub const SO: u8 = 0x0E;
    /// Shift In, switch to G0 (normal half of character set)
    pub const SI: u8 = 0x0F;
    /// Data Link Escape, interpret next control character specially
    pub const DLE: u8 = 0x10;
    /// (DC1) Terminal is allowed to resume transmitting
    pub const XON: u8 = 0x11;
    /// Device Control 2, causes ASR-33 to activate paper-tape reader
    pub const DC2: u8 = 0x12;
    /// (DC2) Terminal must pause and refrain from transmitting
    pub const XOFF: u8 = 0x13;
    /// Device Control 4, causes ASR-33 to deactivate paper-tape reader
    pub const DC4: u8 = 0x14;
    /// Negative Acknowledge, used sometimes with ETX and ACK
    pub const NAK: u8 = 0x15;
    /// Synchronous Idle, used to maintain timing in Sync communication
    pub const SYN: u8 = 0x16;
    /// End of Transmission block
    pub const ETB: u8 = 0x17;
    /// Cancel (makes VT100 abort current escape sequence if any)
    pub const CAN: u8 = 0x18;
    /// End of Medium
    pub const EM: u8 = 0x19;
    /// Substitute (VT100 uses this to display parity errors)
    pub const SUB: u8 = 0x1A;
    /// Prefix to an escape sequence
    pub const ESC: u8 = 0x1B;
    /// File Separator
    pub const FS: u8 = 0x1C;
    /// Group Separator
    pub const GS: u8 = 0x1D;
    /// Record Separator (sent by VT132 in block-transfer mode)
    pub const RS: u8 = 0x1E;
    /// Unit Separator
    pub const US: u8 = 0x1F;
    /// Delete, should be ignored by terminal
    pub const DEL: u8 = 0x7f;
}


/// C1 set of 8-bit control characters (from ANSI X3.64-1979)
///
/// 0x80 (@), 0x81 (A), 0x82 (B), 0x83 (C) are reserved
/// 0x98 (X), 0x99 (Y) are reserved
/// 0x9a (Z) is resezved, but causes DEC terminals to respond with DA codes
#[allow(non_snake_case)]
pub mod C1 {
    /// Reserved
    pub const PAD: u8 = 0x80;
    /// Reserved
    pub const HOP: u8 = 0x81;
    /// Reserved
    pub const BPH: u8 = 0x82;
    /// Reserved
    pub const NBH: u8 = 0x83;
    /// Index, moves down one line same column regardless of NL
    pub const IND: u8 = 0x84;
    /// New line, moves done one line and to first column (CR+LF)
    pub const NEL: u8 = 0x85;
    /// Start of Selected Area to be  as charsent to auxiliary output device
    pub const SSA: u8 = 0x86;
    /// End of Selected Area to be sent to auxiliary output device
    pub const ESA: u8 = 0x87;
    /// Horizontal Tabulation Set at current position
    pub const HTS: u8 = 0x88;
    /// Hor Tab Justify, moves string to next tab position
    pub const HTJ: u8 = 0x89;
    /// Vertical Tabulation Set at current line
    pub const VTS: u8 = 0x8A;
    /// Partial Line Down (subscript)
    pub const PLD: u8 = 0x8B;
    /// Partial Line Up (superscript)
    pub const PLU: u8 = 0x8C;
    /// Reverse Index, go up one line, reverse scroll if necessary
    pub const RI: u8 = 0x8D;
    /// Single Shift to G2
    pub const SS2: u8 = 0x8E;
    /// Single Shift to G3 (VT100 uses this for sending PF keys)
    pub const SS3: u8 = 0x8F;
    /// Device Control String, terminated by ST (VT125 enters graphics)
    pub const DCS: u8 = 0x90;
    /// Private Use 1
    pub const PU1: u8 = 0x91;
    /// Private Use 2
    pub const PU2: u8 = 0x92;
    /// Set Transmit State
    pub const STS: u8 = 0x93;
    /// Cancel character, ignore previous character
    pub const CCH: u8 = 0x94;
    /// Message Waiting, turns on an indicator on the terminal
    pub const MW: u8 = 0x95;
    /// Start of Protected Area
    pub const SPA: u8 = 0x96;
    /// End of Protected Area
    pub const EPA: u8 = 0x97;
    /// SOS
    pub const SOS: u8 = 0x98;
    /// SGCI
    pub const SGCI: u8 = 0x99;
    /// DECID - Identify Terminal
    pub const DECID: u8 = 0x9a;
    /// Control Sequence Introducer (described in a seperate table)
    pub const CSI: u8 = 0x9B;
    /// String Terminator (VT125 exits graphics)
    pub const ST: u8 = 0x9C;
    /// Operating System Command (reprograms intelligent terminal)
    pub const OSC: u8 = 0x9D;
    /// Privacy Message (password verification), terminated by ST
    pub const PM: u8 = 0x9E;
    /// Application Program Command (to word processor), term by ST
    pub const APC: u8 = 0x9F;
}

// Tests for parsing escape sequences
//
// Byte sequences used in these tests are recording of pty stdout.
#[cfg(test)]
mod tests {
    use std::io;
    use index::{Line, Column};
    use super::{Processor, Handler, Attr, TermInfo, Color, StandardCharset, CharsetIndex};
    use ::Rgb;

    /// The /dev/null of io::Write
    struct Void;

    impl io::Write for Void {
        fn write(&mut self, bytes: &[u8]) -> io::Result<usize> {
            Ok(bytes.len())
        }

        fn flush(&mut self) -> io::Result<()> {
            Ok(())
        }
    }

    #[derive(Default)]
    struct AttrHandler {
        attr: Option<Attr>,
    }

    impl Handler for AttrHandler {
        fn terminal_attribute(&mut self, attr: Attr) {
            self.attr = Some(attr);
        }
    }

    impl TermInfo for AttrHandler {
        fn lines(&self) -> Line {
            Line(24)
        }

        fn cols(&self) -> Column {
            Column(80)
        }
    }

    #[test]
    fn parse_control_attribute() {
        static BYTES: &'static [u8] = &[
            0x1b, 0x5b, 0x31, 0x6d
        ];

        let mut parser = Processor::new();
        let mut handler = AttrHandler::default();

        for byte in &BYTES[..] {
            parser.advance(&mut handler, *byte, &mut Void);
        }

        assert_eq!(handler.attr, Some(Attr::Bold));
    }

    #[test]
    fn parse_truecolor_attr() {
        static BYTES: &'static [u8] = &[
            0x1b, 0x5b, 0x33, 0x38, 0x3b, 0x32, 0x3b, 0x31, 0x32,
            0x38, 0x3b, 0x36, 0x36, 0x3b, 0x32, 0x35, 0x35, 0x6d
        ];

        let mut parser = Processor::new();
        let mut handler = AttrHandler::default();

        for byte in &BYTES[..] {
            parser.advance(&mut handler, *byte, &mut Void);
        }

        let spec = Rgb {
            r: 128,
            g: 66,
            b: 255
        };

        assert_eq!(handler.attr, Some(Attr::Foreground(Color::Spec(spec))));
    }

    /// No exactly a test; useful for debugging
    #[test]
    fn parse_zsh_startup() {
        static BYTES: &'static [u8] = &[
            0x1b, 0x5b, 0x31, 0x6d, 0x1b, 0x5b, 0x37, 0x6d, 0x25, 0x1b, 0x5b,
            0x32, 0x37, 0x6d, 0x1b, 0x5b, 0x31, 0x6d, 0x1b, 0x5b, 0x30, 0x6d,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
            0x20, 0x20, 0x0d, 0x20, 0x0d, 0x0d, 0x1b, 0x5b, 0x30, 0x6d, 0x1b,
            0x5b, 0x32, 0x37, 0x6d, 0x1b, 0x5b, 0x32, 0x34, 0x6d, 0x1b, 0x5b,
            0x4a, 0x6a, 0x77, 0x69, 0x6c, 0x6d, 0x40, 0x6a, 0x77, 0x69, 0x6c,
            0x6d, 0x2d, 0x64, 0x65, 0x73, 0x6b, 0x20, 0x1b, 0x5b, 0x30, 0x31,
            0x3b, 0x33, 0x32, 0x6d, 0xe2, 0x9e, 0x9c, 0x20, 0x1b, 0x5b, 0x30,
            0x31, 0x3b, 0x33, 0x32, 0x6d, 0x20, 0x1b, 0x5b, 0x33, 0x36, 0x6d,
            0x7e, 0x2f, 0x63, 0x6f, 0x64, 0x65
        ];

        let mut handler = AttrHandler::default();
        let mut parser = Processor::new();

        for byte in &BYTES[..] {
            parser.advance(&mut handler, *byte, &mut Void);
        }
    }

    struct CharsetHandler {
        index: CharsetIndex,
        charset: StandardCharset,
    }

    impl Default for CharsetHandler {
        fn default() -> CharsetHandler {
            CharsetHandler {
                index: CharsetIndex::G0,
                charset: StandardCharset::Ascii,
            }
        }
    }

    impl Handler for CharsetHandler {
        fn configure_charset(&mut self, index: CharsetIndex, charset: StandardCharset) {
            self.index = index;
            self.charset = charset;
        }

        fn set_active_charset(&mut self, index: CharsetIndex) {
            self.index = index;
        }
    }

    impl TermInfo for CharsetHandler {
        fn lines(&self) -> Line { Line(200) }
        fn cols(&self) -> Column { Column(90) }
    }

    #[test]
    fn parse_designate_g0_as_line_drawing() {
        static BYTES: &'static [u8] = &[0x1b, b'(', b'0'];
        let mut parser = Processor::new();
        let mut handler = CharsetHandler::default();

        for byte in &BYTES[..] {
            parser.advance(&mut handler, *byte, &mut Void);
        }

        assert_eq!(handler.index, CharsetIndex::G0);
        assert_eq!(handler.charset, StandardCharset::SpecialCharacterAndLineDrawing);
    }

    #[test]
    fn parse_designate_g1_as_line_drawing_and_invoke() {
        static BYTES: &'static [u8] = &[0x1b, 0x29, 0x30, 0x0e];
        let mut parser = Processor::new();
        let mut handler = CharsetHandler::default();

        for byte in &BYTES[..3] {
            parser.advance(&mut handler, *byte, &mut Void);
        }

        assert_eq!(handler.index, CharsetIndex::G1);
        assert_eq!(handler.charset, StandardCharset::SpecialCharacterAndLineDrawing);

        let mut handler = CharsetHandler::default();
        parser.advance(&mut handler, BYTES[3], &mut Void);

        assert_eq!(handler.index, CharsetIndex::G1);
    }
}
