//! Kill Ring management
use line_buffer::{DeleteListener, Direction};

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum Action {
    Kill,
    Yank(usize),
    Other,
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Mode {
    Append,
    Prepend,
}

pub struct KillRing {
    slots: Vec<String>,
    // where we are in the kill ring
    index: usize,
    // whether or not the last command was a kill or a yank
    last_action: Action,
    killing: bool,
}

impl KillRing {
    /// Create a new kill-ring of the given `size`.
    pub fn new(size: usize) -> KillRing {
        KillRing {
            slots: Vec::with_capacity(size),
            index: 0,
            last_action: Action::Other,
            killing: false,
        }
    }

    /// Reset `last_action` state.
    pub fn reset(&mut self) {
        self.last_action = Action::Other;
    }

    /// Add `text` to the kill-ring.
    pub fn kill(&mut self, text: &str, dir: Mode) {
        match self.last_action {
            Action::Kill => {
                if self.slots.capacity() == 0 {
                    // disabled
                    return;
                }
                match dir {
                    Mode::Append => self.slots[self.index].push_str(text),
                    Mode::Prepend => self.slots[self.index].insert_str(0, text),
                };
            }
            _ => {
                self.last_action = Action::Kill;
                if self.slots.capacity() == 0 {
                    // disabled
                    return;
                }
                if self.index == self.slots.capacity() - 1 {
                    // full
                    self.index = 0;
                } else if !self.slots.is_empty() {
                    self.index += 1;
                }
                if self.index == self.slots.len() {
                    self.slots.push(String::from(text))
                } else {
                    self.slots[self.index] = String::from(text);
                }
            }
        }
    }

    /// Yank previously killed text.
    /// Return `None` when kill-ring is empty.
    pub fn yank(&mut self) -> Option<&String> {
        if self.slots.is_empty() {
            None
        } else {
            self.last_action = Action::Yank(self.slots[self.index].len());
            Some(&self.slots[self.index])
        }
    }

    /// Yank killed text stored in previous slot.
    /// Return `None` when the previous command was not a yank.
    pub fn yank_pop(&mut self) -> Option<(usize, &String)> {
        match self.last_action {
            Action::Yank(yank_size) => {
                if self.slots.is_empty() {
                    return None;
                }
                if self.index == 0 {
                    self.index = self.slots.len() - 1;
                } else {
                    self.index -= 1;
                }
                self.last_action = Action::Yank(self.slots[self.index].len());
                Some((yank_size, &self.slots[self.index]))
            }
            _ => None,
        }
    }
}

impl DeleteListener for KillRing {
    fn start_killing(&mut self) {
        self.killing = true;
    }

    fn delete(&mut self, _: usize, string: &str, dir: Direction) {
        if !self.killing {
            return;
        }
        let mode = match dir {
            Direction::Forward => Mode::Append,
            Direction::Backward => Mode::Prepend,
        };
        self.kill(string, mode);
    }

    fn stop_killing(&mut self) {
        self.killing = false;
    }
}

#[cfg(test)]
mod tests {
    use super::{Action, KillRing, Mode};

    #[test]
    fn disabled() {
        let mut kill_ring = KillRing::new(0);
        kill_ring.kill("text", Mode::Append);
        assert!(kill_ring.slots.is_empty());
        assert_eq!(0, kill_ring.index);
        assert_eq!(Action::Kill, kill_ring.last_action);

        assert_eq!(None, kill_ring.yank());
        assert_eq!(Action::Kill, kill_ring.last_action);
    }

    #[test]
    fn one_kill() {
        let mut kill_ring = KillRing::new(2);
        kill_ring.kill("word1", Mode::Append);
        assert_eq!(0, kill_ring.index);
        assert_eq!(1, kill_ring.slots.len());
        assert_eq!("word1", kill_ring.slots[0]);
        assert_eq!(Action::Kill, kill_ring.last_action);
    }

    #[test]
    fn kill_append() {
        let mut kill_ring = KillRing::new(2);
        kill_ring.kill("word1", Mode::Append);
        kill_ring.kill(" word2", Mode::Append);
        assert_eq!(0, kill_ring.index);
        assert_eq!(1, kill_ring.slots.len());
        assert_eq!("word1 word2", kill_ring.slots[0]);
        assert_eq!(Action::Kill, kill_ring.last_action);
    }

    #[test]
    fn kill_backward() {
        let mut kill_ring = KillRing::new(2);
        kill_ring.kill("word1", Mode::Prepend);
        kill_ring.kill("word2 ", Mode::Prepend);
        assert_eq!(0, kill_ring.index);
        assert_eq!(1, kill_ring.slots.len());
        assert_eq!("word2 word1", kill_ring.slots[0]);
        assert_eq!(Action::Kill, kill_ring.last_action);
    }

    #[test]
    fn kill_other_kill() {
        let mut kill_ring = KillRing::new(2);
        kill_ring.kill("word1", Mode::Append);
        kill_ring.reset();
        kill_ring.kill("word2", Mode::Append);
        assert_eq!(1, kill_ring.index);
        assert_eq!(2, kill_ring.slots.len());
        assert_eq!("word1", kill_ring.slots[0]);
        assert_eq!("word2", kill_ring.slots[1]);
        assert_eq!(Action::Kill, kill_ring.last_action);
    }

    #[test]
    fn many_kill() {
        let mut kill_ring = KillRing::new(2);
        kill_ring.kill("word1", Mode::Append);
        kill_ring.reset();
        kill_ring.kill("word2", Mode::Append);
        kill_ring.reset();
        kill_ring.kill("word3", Mode::Append);
        kill_ring.reset();
        kill_ring.kill("word4", Mode::Append);
        assert_eq!(1, kill_ring.index);
        assert_eq!(2, kill_ring.slots.len());
        assert_eq!("word3", kill_ring.slots[0]);
        assert_eq!("word4", kill_ring.slots[1]);
        assert_eq!(Action::Kill, kill_ring.last_action);
    }

    #[test]
    fn yank() {
        let mut kill_ring = KillRing::new(2);
        kill_ring.kill("word1", Mode::Append);
        kill_ring.reset();
        kill_ring.kill("word2", Mode::Append);

        assert_eq!(Some(&"word2".to_owned()), kill_ring.yank());
        assert_eq!(Action::Yank(5), kill_ring.last_action);
        assert_eq!(Some(&"word2".to_owned()), kill_ring.yank());
        assert_eq!(Action::Yank(5), kill_ring.last_action);
    }

    #[test]
    fn yank_pop() {
        let mut kill_ring = KillRing::new(2);
        kill_ring.kill("word1", Mode::Append);
        kill_ring.reset();
        kill_ring.kill("longword2", Mode::Append);

        assert_eq!(None, kill_ring.yank_pop());
        kill_ring.yank();
        assert_eq!(Some((9, &"word1".to_owned())), kill_ring.yank_pop());
        assert_eq!(Some((5, &"longword2".to_owned())), kill_ring.yank_pop());
        assert_eq!(Some((9, &"word1".to_owned())), kill_ring.yank_pop());
    }
}
