//! Meka file container

use serde_json::Value;
use std::{collections::BTreeMap, fs::File, io::Write, path::PathBuf};

use crate::{errors::MekaError, utils::ProgramData};

/// Meka file
#[derive(serde::Serialize, serde::Deserialize, Debug, Default, Clone)]
#[serde(default)]
pub struct MekaFile {
    /// processes list
    pub processes: BTreeMap<i32, ProgramData>,
}

impl MekaFile {
    /// Try to parse a Meka file
    /// # Errors
    /// Returns errors on failure
    pub fn try_from_file(input_file: PathBuf) -> Result<Self, MekaError> {
        let file = File::open(&input_file).map_err(|e| {
            MekaError::new(format!("Cannot open file {}: {e}", input_file.display()))
        })?;
        let parsed_file: Self = serde_json::from_reader(file).map_err(|e| {
            MekaError::new(format!(
                "Cannot parse json from {}: {e}",
                input_file.display()
            ))
        })?;
        Ok(parsed_file)
    }

    /// Write file as json to output_file
    /// # Errors
    /// Returns errors on failure
    pub fn write_value(value: Value, output_file: &PathBuf) -> Result<(), MekaError> {
        let json_data = serde_json::to_string_pretty(&value)
            .map_err(|e| MekaError::new(format!("Cannot stringify json: {e}")))?;
        let mut file = File::create(output_file).map_err(|e| {
            MekaError::new(format!("Cannot open file {}: {e}", output_file.display()))
        })?;
        file.write_all(json_data.as_bytes()).map_err(|e| {
            MekaError::new(format!(
                "Cannot write json to {}: {e}",
                output_file.display()
            ))
        })?;
        Ok(())
    }
}
