1#[path = "system/array.rs"]
2mod array;
3#[path = "system/array_retrive.rs"]
4mod array_tools;
5#[path = "auth.rs"]
6mod auth;
7#[path = "system/config.rs"]
8mod config;
9#[path = "system/encrypt.rs"]
10mod encrypt;
11#[path = "enviornment.rs"]
13mod local_env;
14#[path = "system/secrets.rs"]
15mod secret;
16use dusa_collection_utils::log;
17use dusa_collection_utils::core::logger::LogLevel;
18use dusa_collection_utils::core::types::pathtype::PathType;
19use dusa_collection_utils::core::types::stringy::Stringy;
20use dusa_collection_utils::{
21 core::errors::{ErrorArrayItem, OkWarning, UnifiedResult as uf},
22 platform::functions::{create_hash, path_present},
23};
24use local_env::{clean_temps, VERSION};
25use secret::{read_raw, write_raw};
26
27use std::{
28 fs::{File, OpenOptions},
29 io::{Read, Write},
30};
31
32use crate::{
33 array::{index_system_array, ChunkMap},
34 array_tools::fetch_chunk,
35 config::{ARRAY_LEN, CHUNK_SIZE},
36 local_env::{set_system, SystemPaths},
37 secret::{forget, read, write},
38};
39
40pub static mut DEBUGGING: Option<bool> = None;
42
43pub static mut PROGNAME: &str = "";
46
47pub fn set_debug(option: bool) {
53 match option {
55 true => unsafe { DEBUGGING = Some(true) },
56 false => unsafe { DEBUGGING = Some(false) },
57 }
58}
59
60pub fn set_prog(data: &'static str) {
66 unsafe { PROGNAME = data };
67}
68
69pub async fn initialize(temporary_path: bool) -> uf<()> {
80 let debugging: bool = match unsafe { DEBUGGING } {
81 Some(d) => match d {
82 true => true,
83 false => false,
84 },
85 None => false,
86 };
87
88 let debug: bool = match &debugging {
89 true => {
90 use std::env;
91 env::set_var("RUST_BACKTRACE", "1");
92 true
93 }
94 false => false,
95 };
96
97 log!(LogLevel::Trace, "RECS started");
98
99 SystemPaths::set_current(temporary_path).await;
100
101 if let Err(e) = ensure_system_path(debug).await.uf_unwrap() {
102 return uf::new(Err(e));
103 }
104
105 if let Err(e) = ensure_max_map_exists().await.uf_unwrap() {
106 return uf::new(Err(e));
107 }
108
109 uf::new(Ok(()))
110}
111
112async fn ensure_system_path(debug: bool) -> uf<()> {
124 let system_paths = SystemPaths::read_current().await;
125
126 match path_present(&system_paths.SYSTEM_ARRAY_LOCATION).uf_unwrap() {
127 Ok(true) => (),
128 Ok(false) => {
129 log!(
130 LogLevel::Trace,
131 "System array file does not exist, reinitialize recs"
132 );
133 if let Err(e) = set_system(debug).await.uf_unwrap() {
134 return uf::new(Err(e));
135 }
136 }
137 Err(e) => return uf::new(Err(e)),
138 }
139
140 uf::new(Ok(()))
141}
142
143async fn ensure_max_map_exists() -> uf<()> {
154 let system_paths = SystemPaths::read_current().await;
155 let max_map = ARRAY_LEN / CHUNK_SIZE;
156 let max_map_path = PathType::Content(format!("{}/{}.map", system_paths.MAPS, max_map - 1));
157
158 match path_present(&max_map_path).uf_unwrap() {
159 Ok(true) => uf::new(Ok(())),
160 Ok(false) => match index_system_array().await.uf_unwrap() {
161 Ok(_d) => uf::new(Ok(())),
162 Err(e) => return uf::new(Err(e)),
163 },
164 Err(e) => uf::new(Err(e)),
165 }
166}
167
168pub async fn store(filename: PathType, owner: String, name: String) -> uf<()> {
182 match write(filename, owner, name, false).await.uf_unwrap() {
183 Ok(d) => {
184 log!(LogLevel::Info, "Stored: value:{}, count: {} ", d.0, d.1);
185 return uf::new(Ok(()));
186 }
187 Err(e) => return uf::new(Err(e)),
188 }
189}
190
191pub async fn retrieve(
205 owner: String,
206 name: String,
207 uid: u32,
208) -> uf<OkWarning<(PathType, PathType)>> {
209 read(owner, name, uid, false).await
210}
211
212pub async fn remove(owner: String, name: String) -> uf<()> {
225 match forget(owner, name).await {
226 Ok(_) => uf::new(Ok(())),
227 Err(err) => uf::new(Err(err)),
228 }
229}
230
231pub async fn ping(owner: String, name: String) -> uf<bool> {
243 let system_paths: SystemPaths = SystemPaths::read_current().await;
244 let secret_map_path = PathType::Content(format!(
245 "{}/{owner}-{name}.meta",
246 system_paths.META,
247 owner = owner,
248 name = name
249 ));
250 path_present(&secret_map_path)
251}
252
253pub async fn encrypt_raw(data: String) -> uf<(String, String, usize)> {
265 write_raw(data.into()).await
266}
267
268pub fn decrypt_raw(recs_data: String, recs_key: String, recs_chunks: usize) -> uf<Vec<u8>> {
282 read_raw(recs_data, recs_key, recs_chunks)
283}
284
285pub async fn house_keeping() -> Result<(), ErrorArrayItem> {
292 let handle: tokio::task::JoinHandle<Result<(), ErrorArrayItem>> = tokio::spawn(async {
293 clean_temps().await?;
294 ensure_max_map_exists().await.uf_unwrap()?;
295 Ok(())
296 });
297
298 match handle.await {
299 Ok(result) => {
300 match result {
301 Ok(_) => Ok(()),
302 Err(err) => Err(err),
303 }
304 },
305 Err(err) => Err(ErrorArrayItem::new(
306 dusa_collection_utils::core::errors::Errors::GeneralError,
307 err.to_string(),
308 )),
309 }
310}
311
312pub async fn update_map(map_num: u32) -> bool {
324 let system_paths: SystemPaths = SystemPaths::read_current().await;
325 let map_path: PathType =
328 PathType::Content(format!("{}/chunk_{}.map", system_paths.MAPS, map_num));
329
330 let mut map_file = File::open(&map_path).expect("File could not be opened");
332 let mut map_data: String = String::new();
333
334 map_file
335 .read_to_string(&mut map_data)
336 .expect("Could not read the map file !");
337
338 let pretty_map_data: ChunkMap = serde_json::from_str(&map_data).unwrap();
340
341 let chunk_data: (bool, Option<String>) = match fetch_chunk(map_num).await.uf_unwrap() {
343 Ok(data) => (true, Some(data)),
344 Err(_) => (false, None),
345 };
346
347 let new_hash: Option<Stringy> = match chunk_data {
348 (true, None) => None,
349 (true, Some(chunk)) => Some(create_hash(chunk)),
350 (false, None) => None,
351 (false, Some(_)) => None,
352 };
353
354 if new_hash == None {
355 log!(
356 LogLevel::Error,
357 "Failed to fetch chunk data for number {}",
358 &map_num
359 );
360 }
361
362 let new_map: ChunkMap = ChunkMap {
364 location: pretty_map_data.location,
365 version: VERSION.to_string(),
366 chunk_num: pretty_map_data.chunk_num,
367 chunk_hsh: new_hash.unwrap(),
368 chunk_beg: pretty_map_data.chunk_beg,
369 chunk_end: pretty_map_data.chunk_end,
370 };
371
372 let _ = map_path.delete();
374 let updated_map = serde_json::to_string_pretty(&new_map).unwrap();
375
376 let mut map_file = OpenOptions::new()
377 .create_new(true)
378 .write(true)
379 .append(true)
380 .open(map_path)
381 .expect("File could not written to");
382
383 if let Err(_e) = writeln!(map_file, "{}", updated_map) {
384 log!(LogLevel::Error, "Could save map data to file");
385 };
386
387 return true;
388}