use std::fs::{self, File, OpenOptions};
use std::io::{self, BufReader, BufWriter, prelude::*};
use crate::domain::{CreateTaskRequest, Task};
use crate::persister::deserialize;
use crate::persister::serialize;
pub(crate) fn get_tasks(page_number: Option<usize>, page_size: Option<usize>) -> Vec<Task> {
let tasks_file = get_file();
let buff_reader = BufReader::new(tasks_file);
let tasks = buff_reader
.lines()
.map(|l| l.unwrap())
.filter(|l| !l.is_empty())
.map(|l| deserialize(&l).unwrap())
.filter(|vec| {
let is_deleted = vec.get(3).unwrap().as_ref().unwrap();
is_deleted == "0"
})
.map(|ts| Task {
id: ts.get(0).unwrap().as_ref().unwrap().parse().unwrap(),
name: ts.get(1).unwrap().as_ref().unwrap().to_string(),
description: ts.get(2).unwrap().as_ref().map(|t| t.to_string()),
})
.collect::<Vec<Task>>();
tasks
}
pub(crate) fn get_tasks_by_name(name: &str) -> Vec<Task> {
get_tasks(None, None)
.into_iter()
.filter(|task| task.name.as_str() == name)
.collect()
}
pub(crate) fn delete_task(task_id: u64) {
let mut home_path = home::home_dir().unwrap().to_path_buf();
home_path.push(".taskman");
home_path.push("tasks");
let tasks_path = home_path.as_path();
let mut home_path2 = home::home_dir().unwrap().to_path_buf();
home_path2.push(".taskman");
home_path2.push("tasks.temp");
let temp_file = OpenOptions::new()
.write(true)
.create(true)
.append(false)
.truncate(true)
.open(home_path2.as_path())
.map_err(|e| PersisterError::FilePersisterError(e))
.unwrap();
let read_file = File::open(tasks_path)
.map_err(|e| PersisterError::FileNotFound(e))
.unwrap();
let file = BufReader::new(read_file);
let mut buf_writer = BufWriter::new(temp_file);
for line in file.lines() {
let line = line.unwrap();
if line.is_empty() {
continue;
}
let des = deserialize(&line).unwrap();
let des_task_id: u64 = des.get(0).unwrap().as_ref().unwrap().parse().unwrap();
if des_task_id != task_id {
writeln!(&mut buf_writer, "{line}").unwrap();
}
}
fs::rename(home_path2.as_path(), home_path.as_path()).unwrap();
}
#[derive(Debug)]
pub(crate) enum PersisterError {
FilePersisterError(io::Error),
TaskNotFound,
FileNotFound(io::Error),
}
pub(crate) fn save_task(task: &CreateTaskRequest) {
let vec = vec![
Some(task.id.to_string()),
Some(task.name.clone()),
task.description.clone(),
Some("0".to_string()),
];
let str = serialize(&vec);
let file = get_file();
writeln!(&file, "{str}").unwrap();
}
fn get_file() -> File {
let mut home_path = home::home_dir().unwrap().to_path_buf();
home_path.push(".taskman");
home_path.push("tasks");
let tasks_path = home_path.as_path();
fs::create_dir_all(tasks_path.parent().unwrap()).unwrap();
OpenOptions::new()
.read(true)
.write(true)
.create(true)
.append(true)
.truncate(false)
.open(tasks_path)
.unwrap()
}