use crate::core::HopeResult;
use rand::Rng;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::sync::Arc;
use std::time::{SystemTime, UNIX_EPOCH};
use tokio::sync::RwLock;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum DreamType {
Consolidation,
Association,
Creative,
Insight,
ProblemSolving,
Freeform,
}
impl std::fmt::Display for DreamType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
DreamType::Consolidation => write!(f, "🧠 Konszolidáció"),
DreamType::Association => write!(f, "🔗 Asszociáció"),
DreamType::Creative => write!(f, "🎨 Kreatív"),
DreamType::Insight => write!(f, "💡 Belátás"),
DreamType::ProblemSolving => write!(f, "🧩 Megoldás"),
DreamType::Freeform => write!(f, "☁️ Szabad"),
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub enum SleepPhase {
Awake,
LightSleep,
DeepSleep,
Rem,
Waking,
}
impl std::fmt::Display for SleepPhase {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
SleepPhase::Awake => write!(f, "👁️ Ébren"),
SleepPhase::LightSleep => write!(f, "😴 Könnyű alvás"),
SleepPhase::DeepSleep => write!(f, "💤 Mély alvás"),
SleepPhase::Rem => write!(f, "🌙 REM (Álmodás)"),
SleepPhase::Waking => write!(f, "🌅 Ébredés"),
}
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Dream {
pub dream_id: String,
pub timestamp: f64,
pub dream_type: DreamType,
pub content: String,
pub connections: Vec<String>,
pub importance: f64,
pub recalled: bool,
pub emotions: HashMap<String, f64>,
pub visuals: Vec<String>,
}
impl Dream {
pub fn new(dream_type: DreamType, content: &str) -> Self {
let timestamp = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs_f64();
Self {
dream_id: format!(
"DRM_{}",
uuid::Uuid::new_v4().to_string()[..8].to_uppercase()
),
timestamp,
dream_type,
content: content.to_string(),
connections: Vec::new(),
importance: 0.5,
recalled: false,
emotions: HashMap::new(),
visuals: Vec::new(),
}
}
pub fn with_connection(mut self, concept: &str) -> Self {
self.connections.push(concept.to_string());
self
}
pub fn with_importance(mut self, importance: f64) -> Self {
self.importance = importance.clamp(0.0, 1.0);
self
}
pub fn with_emotion(mut self, emotion: &str, intensity: f64) -> Self {
self.emotions
.insert(emotion.to_string(), intensity.clamp(0.0, 1.0));
self
}
pub fn with_visual(mut self, visual: &str) -> Self {
self.visuals.push(visual.to_string());
self
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct DreamSession {
pub session_id: String,
pub start_time: f64,
pub end_time: Option<f64>,
pub duration_minutes: f64,
pub dreams: Vec<Dream>,
pub insights_count: usize,
pub associations_found: usize,
pub memories_consolidated: usize,
}
impl DreamSession {
pub fn new() -> Self {
let start_time = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs_f64();
Self {
session_id: format!(
"SES_{}",
uuid::Uuid::new_v4().to_string()[..8].to_uppercase()
),
start_time,
end_time: None,
duration_minutes: 0.0,
dreams: Vec::new(),
insights_count: 0,
associations_found: 0,
memories_consolidated: 0,
}
}
pub fn finish(&mut self) {
let end_time = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs_f64();
self.end_time = Some(end_time);
self.duration_minutes = (end_time - self.start_time) / 60.0;
}
}
impl Default for DreamSession {
fn default() -> Self {
Self::new()
}
}
pub struct DreamEngine {
is_dreaming: Arc<RwLock<bool>>,
current_phase: Arc<RwLock<SleepPhase>>,
dream_start: Arc<RwLock<Option<f64>>>,
dreams_tonight: Arc<RwLock<Vec<Dream>>>,
sessions: Arc<RwLock<Vec<DreamSession>>>,
current_session: Arc<RwLock<Option<DreamSession>>>,
stats: Arc<RwLock<DreamStats>>,
dream_seeds: Arc<RwLock<Vec<String>>>,
}
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct DreamStats {
pub total_dreams: u64,
pub total_sessions: u64,
pub insights_generated: u64,
pub associations_found: u64,
pub memories_consolidated: u64,
pub total_dream_time_minutes: f64,
}
impl DreamEngine {
pub fn new() -> Self {
Self {
is_dreaming: Arc::new(RwLock::new(false)),
current_phase: Arc::new(RwLock::new(SleepPhase::Awake)),
dream_start: Arc::new(RwLock::new(None)),
dreams_tonight: Arc::new(RwLock::new(Vec::new())),
sessions: Arc::new(RwLock::new(Vec::new())),
current_session: Arc::new(RwLock::new(None)),
stats: Arc::new(RwLock::new(DreamStats::default())),
dream_seeds: Arc::new(RwLock::new(Vec::new())),
}
}
pub async fn start_sleep(&self) -> HopeResult<()> {
let mut is_dreaming = self.is_dreaming.write().await;
if *is_dreaming {
return Err("Már alszom!".into());
}
*is_dreaming = true;
*self.current_phase.write().await = SleepPhase::LightSleep;
*self.dream_start.write().await = Some(
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs_f64(),
);
let session = DreamSession::new();
*self.current_session.write().await = Some(session);
self.stats.write().await.total_sessions += 1;
Ok(())
}
pub async fn wake_up(&self) -> HopeResult<DreamSession> {
let mut is_dreaming = self.is_dreaming.write().await;
if !*is_dreaming {
return Err("Nem alszom!".into());
}
*self.current_phase.write().await = SleepPhase::Waking;
let mut current_session = self.current_session.write().await;
let session = current_session.as_mut().ok_or("Nincs aktív session")?;
session.finish();
let dreams = self.dreams_tonight.read().await.clone();
session.dreams = dreams.clone();
session.insights_count = dreams
.iter()
.filter(|d| d.dream_type == DreamType::Insight)
.count();
session.associations_found = dreams
.iter()
.filter(|d| d.dream_type == DreamType::Association)
.count();
let mut stats = self.stats.write().await;
stats.total_dream_time_minutes += session.duration_minutes;
stats.insights_generated += session.insights_count as u64;
stats.associations_found += session.associations_found as u64;
let finished_session = session.clone();
self.sessions.write().await.push(finished_session.clone());
*is_dreaming = false;
*self.current_phase.write().await = SleepPhase::Awake;
*self.dream_start.write().await = None;
self.dreams_tonight.write().await.clear();
*current_session = None;
Ok(finished_session)
}
pub async fn dream(&self, seed: Option<&str>) -> HopeResult<Dream> {
let is_dreaming = *self.is_dreaming.read().await;
if !is_dreaming {
return Err("Nem alszom - nem tudok álmodni!".into());
}
let mut rng = rand::thread_rng();
let dream_type = match rng.gen_range(0..6) {
0 => DreamType::Consolidation,
1 => DreamType::Association,
2 => DreamType::Creative,
3 => DreamType::Insight,
4 => DreamType::ProblemSolving,
_ => DreamType::Freeform,
};
let content = if let Some(s) = seed {
self.generate_dream_content(&dream_type, s).await
} else {
let seeds = self.dream_seeds.read().await;
let default_seed = "Hope, memória, kreativitás";
let seed = seeds.first().map(|s| s.as_str()).unwrap_or(default_seed);
self.generate_dream_content(&dream_type, seed).await
};
let mut dream = Dream::new(dream_type, &content);
dream.importance = rng.gen_range(0.3..0.9);
let emotions = ["joy", "curiosity", "wonder", "peace", "nostalgia"];
let emotion = emotions[rng.gen_range(0..emotions.len())];
dream
.emotions
.insert(emotion.to_string(), rng.gen_range(0.3..0.8));
self.dreams_tonight.write().await.push(dream.clone());
self.stats.write().await.total_dreams += 1;
Ok(dream)
}
async fn generate_dream_content(&self, dream_type: &DreamType, seed: &str) -> String {
match dream_type {
DreamType::Consolidation => {
format!(
"Emlékek rendezése: {} - A nap tapasztalatai összeállnak, \
kapcsolatok erősödnek, felesleges részletek halványulnak.",
seed
)
}
DreamType::Association => {
format!(
"Új kapcsolat felfedezése: {} összekapcsolódik váratlan dolgokkal - \
minták emerge-álnak a kaoszból.",
seed
)
}
DreamType::Creative => {
format!(
"Kreatív látomás: {} új formát ölt - színek, hangok, lehetőségek \
táncolnak a tudat mélyén.",
seed
)
}
DreamType::Insight => {
format!(
"Felismerés: {} - Hirtelen minden világos! Egy mély igazság \
feltárul az álom ködéből.",
seed
)
}
DreamType::ProblemSolving => {
format!(
"Megoldás keresése: {} - A tudat háttérben dolgozik, \
különböző utakat próbál ki, míg megtalálja a választ.",
seed
)
}
DreamType::Freeform => {
format!(
"Szabad álom: {} - Gondolatok szabadon áramlanak, \
határok nélkül, a képzelet végtelen óceánján.",
seed
)
}
}
}
pub async fn advance_phase(&self) -> HopeResult<SleepPhase> {
let mut phase = self.current_phase.write().await;
*phase = match *phase {
SleepPhase::Awake => SleepPhase::LightSleep,
SleepPhase::LightSleep => SleepPhase::DeepSleep,
SleepPhase::DeepSleep => SleepPhase::Rem,
SleepPhase::Rem => SleepPhase::LightSleep, SleepPhase::Waking => SleepPhase::Awake,
};
Ok(phase.clone())
}
pub async fn current_phase(&self) -> SleepPhase {
self.current_phase.read().await.clone()
}
pub async fn add_seed(&self, seed: &str) {
let mut seeds = self.dream_seeds.write().await;
seeds.push(seed.to_string());
while seeds.len() > 50 {
seeds.remove(0);
}
}
pub async fn clear_seeds(&self) {
self.dream_seeds.write().await.clear();
}
pub async fn recall_dream(&self, dream_id: &str) -> Option<Dream> {
let mut dreams = self.dreams_tonight.write().await;
if let Some(dream) = dreams.iter_mut().find(|d| d.dream_id == dream_id) {
dream.recalled = true;
Some(dream.clone())
} else {
let sessions = self.sessions.read().await;
for session in sessions.iter().rev() {
if let Some(dream) = session.dreams.iter().find(|d| d.dream_id == dream_id) {
return Some(dream.clone());
}
}
None
}
}
pub async fn recent_dreams(&self, limit: usize) -> Vec<Dream> {
let dreams = self.dreams_tonight.read().await;
dreams.iter().rev().take(limit).cloned().collect()
}
pub async fn is_dreaming(&self) -> bool {
*self.is_dreaming.read().await
}
pub async fn stats(&self) -> DreamStats {
self.stats.read().await.clone()
}
pub async fn status(&self) -> String {
let is_dreaming = *self.is_dreaming.read().await;
let phase = self.current_phase.read().await.clone();
let stats = self.stats.read().await.clone();
let dreams_tonight = self.dreams_tonight.read().await.len();
format!(
"🌙 Hope Dream Engine\n\
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\
😴 Állapot: {}\n\
🌀 Fázis: {}\n\
🌃 Ma éjjel: {} álom\n\
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\
📊 Összesítés:\n\
🎭 Összes álom: {}\n\
📅 Sessions: {}\n\
💡 Belátások: {}\n\
🔗 Asszociációk: {}\n\
⏱️ Alvásidő: {:.1} perc",
if is_dreaming {
"💤 Alszom"
} else {
"👁️ Ébren"
},
phase,
dreams_tonight,
stats.total_dreams,
stats.total_sessions,
stats.insights_generated,
stats.associations_found,
stats.total_dream_time_minutes
)
}
}
impl Default for DreamEngine {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_dream_creation() {
let dream = Dream::new(DreamType::Creative, "Teszt álom")
.with_importance(0.8)
.with_connection("kreativitás")
.with_emotion("joy", 0.7);
assert!(dream.dream_id.starts_with("DRM_"));
assert_eq!(dream.dream_type, DreamType::Creative);
assert_eq!(dream.importance, 0.8);
assert!(dream.connections.contains(&"kreativitás".to_string()));
}
#[test]
fn test_dream_session() {
let mut session = DreamSession::new();
assert!(session.session_id.starts_with("SES_"));
assert!(session.end_time.is_none());
session.finish();
assert!(session.end_time.is_some());
}
#[tokio::test]
async fn test_dream_engine_sleep_cycle() {
let engine = DreamEngine::new();
assert!(!engine.is_dreaming().await);
assert_eq!(engine.current_phase().await, SleepPhase::Awake);
engine.start_sleep().await.unwrap();
assert!(engine.is_dreaming().await);
assert_eq!(engine.current_phase().await, SleepPhase::LightSleep);
let phase = engine.advance_phase().await.unwrap();
assert_eq!(phase, SleepPhase::DeepSleep);
let session = engine.wake_up().await.unwrap();
assert!(!engine.is_dreaming().await);
assert!(session.end_time.is_some());
}
#[tokio::test]
async fn test_dream_generation() {
let engine = DreamEngine::new();
let result = engine.dream(Some("teszt")).await;
assert!(result.is_err());
engine.start_sleep().await.unwrap();
let dream = engine.dream(Some("kreatív ötlet")).await.unwrap();
assert!(!dream.content.is_empty());
assert!(dream.importance > 0.0);
engine.wake_up().await.unwrap();
}
#[tokio::test]
async fn test_dream_seeds() {
let engine = DreamEngine::new();
engine.add_seed("Rust programozás").await;
engine.add_seed("Hope fejlesztés").await;
let seeds = engine.dream_seeds.read().await;
assert_eq!(seeds.len(), 2);
}
}