use std::collections::HashMap;
use std::fs;
use std::path::{Path, PathBuf};
use anyhow::Context;
use serde::{Deserialize, Serialize};
use super::files::paths::Paths;
use super::{json_from_file, json_to_file_pretty};
#[derive(Debug)]
pub struct PersistentData {
contents: PersistentDataContents,
}
#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(default)]
struct PersistentDataContents {
java: PersistentDataJava,
versions: HashMap<String, PersistentDataVersionInfo>,
}
#[derive(Serialize, Deserialize, Debug)]
struct PersistentDataVersionInfo {
version: String,
}
#[derive(Serialize, Deserialize, Debug)]
struct PersistentDataJavaVersion {
version: String,
path: String,
}
#[derive(Serialize, Deserialize, Default, Debug)]
#[serde(default)]
struct PersistentDataJava {
adoptium: HashMap<String, PersistentDataJavaVersion>,
zulu: HashMap<String, PersistentDataJavaVersion>,
graalvm: HashMap<String, PersistentDataJavaVersion>,
}
pub(crate) enum PersistentDataJavaInstallation {
Adoptium,
Zulu,
GraalVM,
}
impl PersistentDataContents {
pub fn fix(&mut self) {}
}
impl PersistentData {
pub fn open(paths: &Paths) -> anyhow::Result<Self> {
let path = Self::get_path(paths);
let mut contents = if path.exists() {
json_from_file(&path).context("Failed to get JSON contents")?
} else {
PersistentDataContents::default()
};
contents.fix();
Ok(Self { contents })
}
pub fn get_path(paths: &Paths) -> PathBuf {
paths.internal.join("core_persistent.json")
}
pub async fn dump(&mut self, paths: &Paths) -> anyhow::Result<()> {
let path = Self::get_path(paths);
json_to_file_pretty(path, &self.contents)
.context("Failed to write persistent data contents")?;
Ok(())
}
pub(crate) fn update_java_installation(
&mut self,
installation: PersistentDataJavaInstallation,
major_version: &str,
version: &str,
path: &Path,
) -> anyhow::Result<bool> {
let installation = match installation {
PersistentDataJavaInstallation::Adoptium => &mut self.contents.java.adoptium,
PersistentDataJavaInstallation::Zulu => &mut self.contents.java.zulu,
PersistentDataJavaInstallation::GraalVM => &mut self.contents.java.graalvm,
};
let path_str = path.to_string_lossy().to_string();
if let Some(current_version) = installation.get_mut(major_version) {
if current_version.version == version {
Ok(false)
} else {
let current_version_path = PathBuf::from(¤t_version.path);
if current_version_path.exists() {
fs::remove_dir_all(current_version_path)
.context("Failed to remove old Java installation")?;
}
current_version.version = version.to_string();
current_version.path = path_str;
Ok(true)
}
} else {
installation.insert(
major_version.to_string(),
PersistentDataJavaVersion {
version: version.to_string(),
path: path_str,
},
);
Ok(true)
}
}
pub(crate) fn get_java_path(
&self,
installation: PersistentDataJavaInstallation,
version: &str,
) -> Option<PathBuf> {
let installation = match installation {
PersistentDataJavaInstallation::Adoptium => &self.contents.java.adoptium,
PersistentDataJavaInstallation::Zulu => &self.contents.java.zulu,
PersistentDataJavaInstallation::GraalVM => &self.contents.java.graalvm,
};
let version = installation.get(version)?;
Some(PathBuf::from(version.path.clone()))
}
}