//! Unix specific definitions
use std;
use std::io::{self, Read, Stdout, Write};
use std::sync;
use std::sync::atomic;

use libc;
use nix;
use nix::poll::{self, EventFlags};
use nix::sys::signal;
use nix::sys::termios;
use nix::sys::termios::SetArg;
use unicode_segmentation::UnicodeSegmentation;

use super::{truncate, width, Position, RawMode, RawReader, Renderer, Term};
use config::Config;
use consts::{self, KeyPress};
use error;
use line_buffer::LineBuffer;
use Result;

const STDIN_FILENO: libc::c_int = libc::STDIN_FILENO;
const STDOUT_FILENO: libc::c_int = libc::STDOUT_FILENO;

/// Unsupported Terminals that don't support RAW mode
static UNSUPPORTED_TERM: [&'static str; 3] = ["dumb", "cons25", "emacs"];

fn get_win_size() -> (usize, usize) {
    use std::mem::zeroed;

    unsafe {
        let mut size: libc::winsize = zeroed();
        match libc::ioctl(STDOUT_FILENO, libc::TIOCGWINSZ.into(), &mut size) {
            // .into() for FreeBSD
            0 => (size.ws_col as usize, size.ws_row as usize), // TODO getCursorPosition
            _ => (80, 24),
        }
    }
}

/// Check TERM environment variable to see if current term is in our
/// unsupported list
fn is_unsupported_term() -> bool {
    match std::env::var("TERM") {
        Ok(term) => {
            for iter in &UNSUPPORTED_TERM {
                if (*iter).eq_ignore_ascii_case(&term) {
                    return true;
                }
            }
            false
        }
        Err(_) => false,
    }
}

/// Return whether or not STDIN, STDOUT or STDERR is a TTY
fn is_a_tty(fd: libc::c_int) -> bool {
    unsafe { libc::isatty(fd) != 0 }
}

pub type Mode = termios::Termios;

impl RawMode for Mode {
    /// Disable RAW mode for the terminal.
    fn disable_raw_mode(&self) -> Result<()> {
        try!(termios::tcsetattr(STDIN_FILENO, SetArg::TCSADRAIN, self));
        Ok(())
    }
}

// Rust std::io::Stdin is buffered with no way to know if bytes are available.
// So we use low-level stuff instead...
struct StdinRaw {}

impl Read for StdinRaw {
    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
        loop {
            let res = unsafe {
                libc::read(
                    STDIN_FILENO,
                    buf.as_mut_ptr() as *mut libc::c_void,
                    buf.len() as libc::size_t,
                )
            };
            if res == -1 {
                let error = io::Error::last_os_error();
                if error.kind() != io::ErrorKind::Interrupted
                    || SIGWINCH.load(atomic::Ordering::Relaxed)
                {
                    return Err(error);
                }
            } else {
                return Ok(res as usize);
            }
        }
    }
}

/// Console input reader
pub struct PosixRawReader {
    stdin: StdinRaw,
    timeout_ms: i32,
    buf: [u8; 4],
}

impl PosixRawReader {
    fn new(config: &Config) -> Result<PosixRawReader> {
        Ok(PosixRawReader {
            stdin: StdinRaw {},
            timeout_ms: config.keyseq_timeout(),
            buf: [0; 4],
        })
    }

    fn escape_sequence(&mut self) -> Result<KeyPress> {
        // Read the next two bytes representing the escape sequence.
        let seq1 = try!(self.next_char());
        if seq1 == '[' {
            // ESC [ sequences. (CSI)
            let seq2 = try!(self.next_char());
            if seq2.is_digit(10) {
                // Extended escape, read additional byte.
                let seq3 = try!(self.next_char());
                if seq3 == '~' {
                    Ok(match seq2 {
                        '1' | '7' => KeyPress::Home, // tmux, xrvt
                        '2' => KeyPress::Insert,
                        '3' => KeyPress::Delete,    // kdch1
                        '4' | '8' => KeyPress::End, // tmux, xrvt
                        '5' => KeyPress::PageUp,    // kpp
                        '6' => KeyPress::PageDown,  // knp
                        _ => {
                            debug!(target: "rustyline",
                            "unsupported esc sequence: ESC [ {} ~", seq2);
                            KeyPress::UnknownEscSeq
                        }
                    })
                } else if seq3.is_digit(10) {
                    let seq4 = try!(self.next_char());
                    if seq4 == '~' {
                        Ok(match (seq2, seq3) {
                            ('1', '1') => KeyPress::F(1),  // rxvt-unicode
                            ('1', '2') => KeyPress::F(2),  // rxvt-unicode
                            ('1', '3') => KeyPress::F(3),  // rxvt-unicode
                            ('1', '4') => KeyPress::F(4),  // rxvt-unicode
                            ('1', '5') => KeyPress::F(5),  // kf5
                            ('1', '7') => KeyPress::F(6),  // kf6
                            ('1', '8') => KeyPress::F(7),  // kf7
                            ('1', '9') => KeyPress::F(8),  // kf8
                            ('2', '0') => KeyPress::F(9),  // kf9
                            ('2', '1') => KeyPress::F(10), // kf10
                            ('2', '3') => KeyPress::F(11), // kf11
                            ('2', '4') => KeyPress::F(12), // kf12
                            _ => {
                                debug!(target: "rustyline",
                                "unsupported esc sequence: ESC [ {}{} ~", seq1, seq2);
                                KeyPress::UnknownEscSeq
                            }
                        })
                    } else if seq4 == ';' {
                        let seq5 = try!(self.next_char());
                        if seq5.is_digit(10) {
                            let seq6 = try!(self.next_char()); // '~' expected
                            debug!(target: "rustyline",
                            "unsupported esc sequence: ESC [ {}{} ; {} {}", seq2, seq3, seq5, seq6);
                        } else {
                            debug!(target: "rustyline",
                            "unsupported esc sequence: ESC [ {}{} ; {:?}", seq2, seq3, seq5);
                        }
                        Ok(KeyPress::UnknownEscSeq)
                    } else {
                        debug!(target: "rustyline",
                        "unsupported esc sequence: ESC [ {}{} {:?}", seq2, seq3, seq4);
                        Ok(KeyPress::UnknownEscSeq)
                    }
                } else if seq3 == ';' {
                    let seq4 = try!(self.next_char());
                    if seq4.is_digit(10) {
                        let seq5 = try!(self.next_char());
                        if seq2 == '1' {
                            Ok(match (seq4, seq5) {
                                ('5', 'A') => KeyPress::ControlUp,
                                ('5', 'B') => KeyPress::ControlDown,
                                ('5', 'C') => KeyPress::ControlRight,
                                ('5', 'D') => KeyPress::ControlLeft,
                                ('2', 'A') => KeyPress::ShiftUp,
                                ('2', 'B') => KeyPress::ShiftDown,
                                ('2', 'C') => KeyPress::ShiftRight,
                                ('2', 'D') => KeyPress::ShiftLeft,
                                _ => {
                                    debug!(target: "rustyline",
                                    "unsupported esc sequence: ESC [ {} ; {} {}", seq2, seq4, seq5);
                                    KeyPress::UnknownEscSeq
                                }
                            })
                        } else {
                            debug!(target: "rustyline",
                            "unsupported esc sequence: ESC [ {} ; {} {}", seq2, seq4, seq5);
                            Ok(KeyPress::UnknownEscSeq)
                        }
                    } else {
                        debug!(target: "rustyline",
                        "unsupported esc sequence: ESC [ {} ; {:?}", seq2, seq4);
                        Ok(KeyPress::UnknownEscSeq)
                    }
                } else {
                    Ok(match (seq2, seq3) {
                        ('5', 'A') => KeyPress::ControlUp,
                        ('5', 'B') => KeyPress::ControlDown,
                        ('5', 'C') => KeyPress::ControlRight,
                        ('5', 'D') => KeyPress::ControlLeft,
                        _ => {
                            debug!(target: "rustyline",
                            "unsupported esc sequence: ESC [ {} {:?}", seq2, seq3);
                            KeyPress::UnknownEscSeq
                        }
                    })
                }
            } else {
                // ANSI
                Ok(match seq2 {
                    'A' => KeyPress::Up,    // kcuu1
                    'B' => KeyPress::Down,  // kcud1
                    'C' => KeyPress::Right, // kcuf1
                    'D' => KeyPress::Left,  // kcub1
                    'F' => KeyPress::End,
                    'H' => KeyPress::Home, // khome
                    _ => {
                        debug!(target: "rustyline", "unsupported esc sequence: ESC [ {:?}", seq2);
                        KeyPress::UnknownEscSeq
                    }
                })
            }
        } else if seq1 == 'O' {
            // xterm
            // ESC O sequences. (SS3)
            let seq2 = try!(self.next_char());
            Ok(match seq2 {
                'A' => KeyPress::Up,    // kcuu1
                'B' => KeyPress::Down,  // kcud1
                'C' => KeyPress::Right, // kcuf1
                'D' => KeyPress::Left,  // kcub1
                'F' => KeyPress::End,   // kend
                'H' => KeyPress::Home,  // khome
                'P' => KeyPress::F(1),  // kf1
                'Q' => KeyPress::F(2),  // kf2
                'R' => KeyPress::F(3),  // kf3
                'S' => KeyPress::F(4),  // kf4
                _ => {
                    debug!(target: "rustyline", "unsupported esc sequence: ESC O {:?}", seq2);
                    KeyPress::UnknownEscSeq
                }
            })
        } else if seq1 == '\x1b' {
            // ESC ESC
            Ok(KeyPress::Esc)
        } else {
            // TODO ESC-R (r): Undo all changes made to this line.
            Ok(KeyPress::Meta(seq1))
        }
    }
}

// https://tools.ietf.org/html/rfc3629
#[cfg_attr(rustfmt, rustfmt_skip)]
static UTF8_CHAR_WIDTH: [u8; 256] = [
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x1F
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x3F
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x5F
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, // 0x7F
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0x9F
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, // 0xBF
0,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, // 0xDF
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, // 0xEF
4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0, // 0xFF
];

impl RawReader for PosixRawReader {
    fn next_key(&mut self, single_esc_abort: bool) -> Result<KeyPress> {
        let c = try!(self.next_char());

        let mut key = consts::char_to_key_press(c);
        if key == KeyPress::Esc {
            let timeout_ms = if single_esc_abort && self.timeout_ms == -1 {
                0
            } else {
                self.timeout_ms
            };
            let mut fds = [poll::PollFd::new(STDIN_FILENO, EventFlags::POLLIN)];
            match poll::poll(&mut fds, timeout_ms) {
                Ok(n) if n == 0 => {
                    // single escape
                }
                Ok(_) => {
                    // escape sequence
                    key = try!(self.escape_sequence())
                }
                // Err(ref e) if e.kind() == ErrorKind::Interrupted => continue,
                Err(e) => return Err(e.into()),
            }
        }
        debug!(target: "rustyline", "key: {:?}", key);
        Ok(key)
    }

    fn next_char(&mut self) -> Result<char> {
        let n = try!(self.stdin.read(&mut self.buf[..1]));
        if n == 0 {
            return Err(error::ReadlineError::Eof);
        }
        let first = self.buf[0];
        if first >= 128 {
            let width = UTF8_CHAR_WIDTH[first as usize] as usize;
            if width == 0 {
                try!(std::str::from_utf8(&self.buf[..1]));
                unreachable!()
            }
            try!(self.stdin.read_exact(&mut self.buf[1..width]));
            let s = try!(std::str::from_utf8(&self.buf[..width]));
            Ok(s.chars().next().unwrap())
        } else {
            Ok(first as char)
        }
    }
}

/// Console output writer
pub struct PosixRenderer {
    out: Stdout,
    cols: usize, // Number of columns in terminal
}

impl PosixRenderer {
    fn new() -> PosixRenderer {
        let (cols, _) = get_win_size();
        PosixRenderer {
            out: io::stdout(),
            cols,
        }
    }
}

impl Renderer for PosixRenderer {
    fn move_cursor(&mut self, old: Position, new: Position) -> Result<()> {
        use std::fmt::Write;
        let mut ab = String::new();
        if new.row > old.row {
            // move down
            let row_shift = new.row - old.row;
            if row_shift == 1 {
                ab.push_str("\x1b[B");
            } else {
                write!(ab, "\x1b[{}B", row_shift).unwrap();
            }
        } else if new.row < old.row {
            // move up
            let row_shift = old.row - new.row;
            if row_shift == 1 {
                ab.push_str("\x1b[A");
            } else {
                write!(ab, "\x1b[{}A", row_shift).unwrap();
            }
        }
        if new.col > old.col {
            // move right
            let col_shift = new.col - old.col;
            if col_shift == 1 {
                ab.push_str("\x1b[C");
            } else {
                write!(ab, "\x1b[{}C", col_shift).unwrap();
            }
        } else if new.col < old.col {
            // move left
            let col_shift = old.col - new.col;
            if col_shift == 1 {
                ab.push_str("\x1b[D");
            } else {
                write!(ab, "\x1b[{}D", col_shift).unwrap();
            }
        }
        self.write_and_flush(ab.as_bytes())
    }

    fn refresh_line(
        &mut self,
        prompt: &str,
        prompt_size: Position,
        line: &LineBuffer,
        hint: Option<String>,
        current_row: usize,
        old_rows: usize,
    ) -> Result<(Position, Position)> {
        use std::fmt::Write;
        let mut ab = String::new();

        // calculate the position of the end of the input line
        let end_pos = self.calculate_position(line, prompt_size);
        // calculate the desired position of the cursor
        let cursor = self.calculate_position(&line[..line.pos()], prompt_size);

        // self.old_rows < self.cursor.row if the prompt spans multiple lines and if
        // this is the default State.
        let cursor_row_movement = old_rows.checked_sub(current_row).unwrap_or(0);
        // move the cursor down as required
        if cursor_row_movement > 0 {
            write!(ab, "\x1b[{}B", cursor_row_movement).unwrap();
        }
        // clear old rows
        for _ in 0..old_rows {
            ab.push_str("\r\x1b[0K\x1b[A");
        }
        // clear the line
        ab.push_str("\r\x1b[0K");

        // display the prompt
        ab.push_str(prompt);
        // display the input line
        ab.push_str(line);
        // display hint
        if let Some(hint) = hint {
            ab.push_str(truncate(&hint, end_pos.col, self.cols));
        }
        // we have to generate our own newline on line wrap
        if end_pos.col == 0 && end_pos.row > 0 {
            ab.push_str("\n");
        }
        // position the cursor
        let cursor_row_movement = end_pos.row - cursor.row;
        // move the cursor up as required
        if cursor_row_movement > 0 {
            write!(ab, "\x1b[{}A", cursor_row_movement).unwrap();
        }
        // position the cursor within the line
        if cursor.col > 0 {
            write!(ab, "\r\x1b[{}C", cursor.col).unwrap();
        } else {
            ab.push('\r');
        }

        try!(self.write_and_flush(ab.as_bytes()));
        Ok((cursor, end_pos))
    }

    fn write_and_flush(&mut self, buf: &[u8]) -> Result<()> {
        try!(self.out.write_all(buf));
        try!(self.out.flush());
        Ok(())
    }

    /// Control characters are treated as having zero width.
    /// Characters with 2 column width are correctly handled (not splitted).
    #[allow(if_same_then_else)]
    fn calculate_position(&self, s: &str, orig: Position) -> Position {
        let mut pos = orig;
        let mut esc_seq = 0;
        for c in s.graphemes(true) {
            if c == "\n" {
                pos.row += 1;
                pos.col = 0;
                continue;
            }
            let cw = width(c, &mut esc_seq);
            pos.col += cw;
            if pos.col > self.cols {
                pos.row += 1;
                pos.col = cw;
            }
        }
        if pos.col == self.cols {
            pos.col = 0;
            pos.row += 1;
        }
        pos
    }

    /// Clear the screen. Used to handle ctrl+l
    fn clear_screen(&mut self) -> Result<()> {
        self.write_and_flush(b"\x1b[H\x1b[2J")
    }

    /// Check if a SIGWINCH signal has been received
    fn sigwinch(&self) -> bool {
        SIGWINCH.compare_and_swap(true, false, atomic::Ordering::SeqCst)
    }

    /// Try to update the number of columns in the current terminal,
    fn update_size(&mut self) {
        let (cols, _) = get_win_size();
        self.cols = cols;
    }

    fn get_columns(&self) -> usize {
        self.cols
    }
    /// Try to get the number of rows in the current terminal,
    /// or assume 24 if it fails.
    fn get_rows(&self) -> usize {
        let (_, rows) = get_win_size();
        rows
    }
}

static SIGWINCH_ONCE: sync::Once = sync::ONCE_INIT;
static SIGWINCH: atomic::AtomicBool = atomic::ATOMIC_BOOL_INIT;

fn install_sigwinch_handler() {
    SIGWINCH_ONCE.call_once(|| unsafe {
        let sigwinch = signal::SigAction::new(
            signal::SigHandler::Handler(sigwinch_handler),
            signal::SaFlags::empty(),
            signal::SigSet::empty(),
        );
        let _ = signal::sigaction(signal::SIGWINCH, &sigwinch);
    });
}

extern "C" fn sigwinch_handler(_: libc::c_int) {
    SIGWINCH.store(true, atomic::Ordering::SeqCst);
    debug!(target: "rustyline", "SIGWINCH");
}

pub type Terminal = PosixTerminal;

#[derive(Clone, Debug)]
pub struct PosixTerminal {
    unsupported: bool,
    stdin_isatty: bool,
}

impl Term for PosixTerminal {
    type Reader = PosixRawReader;
    type Writer = PosixRenderer;
    type Mode = Mode;

    fn new() -> PosixTerminal {
        let term = PosixTerminal {
            unsupported: is_unsupported_term(),
            stdin_isatty: is_a_tty(STDIN_FILENO),
        };
        if !term.unsupported && term.stdin_isatty && is_a_tty(STDOUT_FILENO) {
            install_sigwinch_handler();
        }
        term
    }

    // Init checks:

    /// Check if current terminal can provide a rich line-editing user
    /// interface.
    fn is_unsupported(&self) -> bool {
        self.unsupported
    }

    /// check if stdin is connected to a terminal.
    fn is_stdin_tty(&self) -> bool {
        self.stdin_isatty
    }

    // Interactive loop:

    fn enable_raw_mode(&self) -> Result<Mode> {
        use nix::errno::Errno::ENOTTY;
        use nix::sys::termios::{ControlFlags, InputFlags, LocalFlags, SpecialCharacterIndices};
        if !self.stdin_isatty {
            try!(Err(nix::Error::from_errno(ENOTTY)));
        }
        let original_mode = try!(termios::tcgetattr(STDIN_FILENO));
        let mut raw = original_mode.clone();
        // disable BREAK interrupt, CR to NL conversion on input,
        // input parity check, strip high bit (bit 8), output flow control
        raw.input_flags &= !(InputFlags::BRKINT
            | InputFlags::ICRNL
            | InputFlags::INPCK
            | InputFlags::ISTRIP
            | InputFlags::IXON);
        // we don't want raw output, it turns newlines into straight linefeeds
        // raw.c_oflag = raw.c_oflag & !(OutputFlags::OPOST); // disable all output
        // processing
        // character-size mark (8 bits)
        raw.control_flags |= ControlFlags::CS8;
        // disable echoing, canonical mode, extended input processing and signals
        raw.local_flags &=
            !(LocalFlags::ECHO | LocalFlags::ICANON | LocalFlags::IEXTEN | LocalFlags::ISIG);
        raw.control_chars[SpecialCharacterIndices::VMIN as usize] = 1; // One character-at-a-time input
        raw.control_chars[SpecialCharacterIndices::VTIME as usize] = 0; // with blocking read
        try!(termios::tcsetattr(STDIN_FILENO, SetArg::TCSADRAIN, &raw));
        Ok(original_mode)
    }

    /// Create a RAW reader
    fn create_reader(&self, config: &Config) -> Result<PosixRawReader> {
        PosixRawReader::new(config)
    }

    fn create_writer(&self) -> PosixRenderer {
        PosixRenderer::new()
    }
}

#[cfg(unix)]
pub fn suspend() -> Result<()> {
    use nix::unistd::Pid;
    // suspend the whole process group
    try!(signal::kill(Pid::from_raw(0), signal::SIGTSTP));
    Ok(())
}

#[cfg(all(unix, test))]
mod test {
    use super::{Position, Renderer};
    use std::io::{self, Stdout};

    #[test]
    fn prompt_with_ansi_escape_codes() {
        let out = io::stdout();
        let pos = out.calculate_position("\x1b[1;32m>>\x1b[0m ", Position::default(), 80);
        assert_eq!(3, pos.col);
        assert_eq!(0, pos.row);
    }

    #[test]
    fn test_unsupported_term() {
        ::std::env::set_var("TERM", "xterm");
        assert_eq!(false, super::is_unsupported_term());

        ::std::env::set_var("TERM", "dumb");
        assert_eq!(true, super::is_unsupported_term());
    }
}
