//! Kill Ring
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,
        }
    }

    pub fn start_killing(&mut self) {
        self.killing = true;
    }
    pub fn stop_killing(&mut self) {
        self.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 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);
    }
}

#[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());
    }
}
