use crate::process;
use crate::process::Process;
use std::error::Error;
use std::io::{stdin, stdout, Write};
use termion::event::Key;
use termion::input::TermRead;
use termion::raw::IntoRawMode;
pub fn run() -> Result<(), Box<dyn Error>> {
let stdin = stdin();
let mut stdout = stdout().into_raw_mode()?;
let mut state = State::new()?;
write!(
stdout,
"{}{}{}{}",
termion::clear::All,
termion::cursor::Goto(1, 1),
process::print_processes(&state.processes, state.idx),
termion::cursor::Hide
)?;
stdout.flush()?;
for c in stdin.keys() {
write!(
stdout,
"{}{}",
termion::cursor::Goto(1, 1),
termion::clear::CurrentLine
)?;
let key = c?;
match key {
Key::Char('q') | Key::Ctrl('c') => break,
Key::Char('r') => state.refresh()?,
Key::Up | Key::Char('k') => state.move_up(),
Key::Down | Key::Char('j') => state.move_down(),
Key::Backspace | Key::Char('d') => {
let current_process = state.processes.get(state.idx);
match current_process {
Some(process) => {
let res = process::kill_process(process);
match res {
Ok(_) => state.remove_process(),
Err(_) => {}
}
}
None => {}
}
}
_ => {}
}
write!(
stdout,
"{}{}",
termion::clear::All,
process::print_processes(&state.processes, state.idx),
)?;
stdout.flush()?;
}
write!(stdout, "{}", termion::cursor::Show)?;
Ok(())
}
#[derive(Debug)]
struct State {
processes: Vec<Process>,
idx: usize,
}
impl State {
fn new() -> Result<State, Box<dyn Error>> {
let processes = State::get_java_prcess()?;
Ok(State::init(processes))
}
fn init(processes: Vec<Process>) -> State {
State { processes, idx: 0 }
}
fn refresh(&mut self) -> Result<(), Box<dyn Error>> {
let processes = State::get_java_prcess()?;
self.processes = processes;
self.idx = 0;
Ok(())
}
fn get_java_prcess() -> Result<Vec<Process>, Box<dyn Error>> {
let processes = process::get_all_process()?;
let java_processes = process::filter_java_process(processes)?;
Ok(java_processes)
}
fn move_down(&mut self) {
if self.idx + 1 < self.processes.len() {
self.idx += 1
};
}
fn move_up(&mut self) {
if self.idx > 0 {
self.idx -= 1
};
}
fn remove_process(&mut self) {
self.processes.remove(self.idx);
if self.idx >= self.processes.len() && self.idx > 0 {
self.idx = self.processes.len() - 1
};
}
}