1use std::fs;
16use std::path::{Path, PathBuf};
17
18use clap::Parser;
19use colored::*;
20use serde_json::json;
21
22use crate::avatars::{get_random_emoji_for_name, load_avatars, save_avatars};
23
24#[derive(Parser, Debug)]
25pub struct IdArgs {
26 pub name: Option<String>,
28
29 #[arg(long)]
31 pub project: bool,
32
33 #[arg(long)]
35 pub clear: bool,
36}
37
38pub fn user_identity_path() -> Option<PathBuf> {
39 let base = std::env::var_os("XDG_CONFIG_HOME")
40 .map(PathBuf::from)
41 .or_else(|| std::env::var_os("HOME").map(|h| PathBuf::from(h).join(".config")))
42 .or_else(|| std::env::var_os("APPDATA").map(PathBuf::from))?;
43
44 Some(base.join("fur").join("identity"))
45}
46
47fn project_identity_path() -> PathBuf {
48 Path::new(".fur").join("identity")
49}
50
51fn read_identity(path: &Path) -> Option<String> {
52 let text = fs::read_to_string(path).ok()?;
53 let name = text.trim().to_string();
54 if name.is_empty() {
55 None
56 } else {
57 Some(name)
58 }
59}
60
61pub fn current_identity() -> Option<(String, &'static str)> {
63 if let Some(name) = read_identity(&project_identity_path()) {
64 return Some((name, "proyecto (.fur/identity)"));
65 }
66 if let Some(name) = user_identity_path().as_deref().and_then(read_identity) {
67 return Some((name, "usuario (config)"));
68 }
69 load_avatars()
70 .get("main")
71 .and_then(|v| v.as_str())
72 .map(|name| (name.to_string(), "avatars.json (main)"))
73}
74
75pub fn run_id(args: IdArgs) {
76 if args.clear {
77 let path = if args.project {
78 project_identity_path()
79 } else {
80 match user_identity_path() {
81 Some(p) => p,
82 None => return eprintln!("❌ No config directory available."),
83 }
84 };
85 let _ = fs::remove_file(&path);
86 println!("✔ Identidad eliminada ({})", path.display());
87 return show();
88 }
89
90 let Some(name) = args.name else {
91 return show();
92 };
93
94 let mut avatars = load_avatars();
97 if avatars.get(&name).is_none() {
98 let emoji = get_random_emoji_for_name(&name);
99 avatars[name.clone()] = json!(emoji);
100 save_avatars(&avatars);
101 println!("[OK] Avatar '{}' creado {}", name, emoji);
102 }
103
104 let path = if args.project {
105 project_identity_path()
106 } else {
107 match user_identity_path() {
108 Some(p) => p,
109 None => return eprintln!("❌ No config directory available."),
110 }
111 };
112
113 if let Some(parent) = path.parent() {
114 let _ = fs::create_dir_all(parent);
115 }
116
117 match fs::write(&path, format!("{}\n", name)) {
118 Ok(_) => println!(
119 "✔ Escribiendo como {} ({})",
120 name.bright_yellow().bold(),
121 path.display()
122 ),
123 Err(e) => eprintln!("❌ No se pudo escribir {}: {}", path.display(), e),
124 }
125}
126
127fn show() {
128 match current_identity() {
129 Some((name, source)) => println!(
130 "{} {}\n {}",
131 "Escribiendo como".bright_black(),
132 name.bright_yellow().bold(),
133 source.bright_black()
134 ),
135 None => println!("Sin identidad. Usa `fur id <nombre>`."),
136 }
137}