use clap::{Parser, Subcommand};
use std::process;
use wasma_client::{
WasmaCore,
ResourceMode, WindowState,
};
fn init_config(output: Option<String>) -> Result<String, String> {
use std::fs;
use wasma_client::parser::{WasmaConfig, UriHandlingConfig, UserConfig, ResourceLimits};
let default_config = WasmaConfig {
uri_handling: UriHandlingConfig {
window_app_spec: "default.app".to_string(),
protocols: vec![],
multi_instances: true,
singularity_instances: false,
compilation_server: None,
},
user_config: UserConfig {
user_withed: "user".to_string(),
groups_withed: vec![],
},
resource_limits: ResourceLimits {
ip_scope: "local".to_string(),
scope_level: 1,
renderer: "cpu".to_string(),
execution_mode: None,
max_memory_mb: Some(1024),
max_vram_mb: Some(512),
cpu_cores: vec![],
},
};
let output_path = output.unwrap_or_else(|| "wasmal.conf".to_string());
let toml_content = toml::to_string_pretty(&default_config)
.map_err(|e| format!("Failed to serialize config: {}", e))?;
fs::write(&output_path, toml_content)
.map_err(|e| format!("Failed to write config file: {}", e))?;
Ok(output_path)
}
fn validate_config(config_path: Option<String>) -> Result<(), String> {
use wasma_client::ConfigParser;
let parser = ConfigParser::new(config_path);
parser.load().map_err(|e| e.to_string())?;
Ok(())
}
fn print_config_info(config_path: Option<String>) -> Result<(), String> {
use wasma_client::ConfigParser;
let parser = ConfigParser::new(config_path);
let config = parser.load().map_err(|e| e.to_string())?;
println!("WASMA Configuration:");
println!(" URI Handling:");
println!(" Window App Spec: {}", config.uri_handling.window_app_spec);
println!(" Protocols: {:?}", config.uri_handling.protocols);
println!(" User Config:");
println!(" User: {}", config.user_config.user_withed);
println!(" Groups: {:?}", config.user_config.groups_withed);
println!(" Resource Limits:");
println!(" IP Scope: {}", config.resource_limits.ip_scope);
println!(" Scope Level: {}", config.resource_limits.scope_level);
println!(" Renderer: {}", config.resource_limits.renderer);
if let Some(mem) = config.resource_limits.max_memory_mb {
println!(" Max Memory: {} MB", mem);
}
if let Some(vram) = config.resource_limits.max_vram_mb {
println!(" Max VRAM: {} MB", vram);
}
println!(" CPU Cores: {:?}", config.resource_limits.cpu_cores);
Ok(())
}
#[derive(Parser)]
#[command(name = "wasma")]
#[command(author = "WASMA Project")]
#[command(version = "1.0.0")]
#[command(about = "Windows Assignment System Monitoring Architecture", long_about = None)]
struct Cli {
#[arg(short, long, value_name = "FILE")]
config: Option<String>,
#[arg(short = 'm', long, value_enum, default_value = "auto")]
resource_mode: ResourceModeArg,
#[arg(short, long)]
verbose: bool,
#[command(subcommand)]
command: Option<Commands>,
}
#[derive(clap::ValueEnum, Clone, Debug)]
enum ResourceModeArg {
Auto,
Manual,
}
impl From<ResourceModeArg> for ResourceMode {
fn from(arg: ResourceModeArg) -> Self {
match arg {
ResourceModeArg::Auto => ResourceMode::Auto,
ResourceModeArg::Manual => ResourceMode::Manual,
}
}
}
#[derive(Subcommand)]
enum Commands {
Gui {
#[arg(short, long, default_value = "1200")]
width: u32,
#[arg(short = 'h', long, default_value = "800")]
height: u32,
},
Init {
#[arg(short, long)]
output: Option<String>,
},
Validate,
Info,
Create {
#[arg(short, long)]
title: String,
#[arg(short, long)]
app_id: String,
#[arg(short, long, default_value = "800")]
width: u32,
#[arg(short = 'h', long, default_value = "600")]
height: u32,
#[arg(short, long)]
manifest: Option<String>,
},
List {
#[arg(short, long)]
detailed: bool,
},
Close {
window_id: u64,
},
Focus {
window_id: u64,
},
Resources {
window_id: u64,
},
State {
window_id: u64,
#[arg(value_enum)]
state: StateArg,
},
Cycle {
#[arg(short, long, default_value = "1")]
count: u32,
},
UClient {
#[arg(short, long)]
raw: bool,
},
}
#[derive(clap::ValueEnum, Clone, Debug)]
enum StateArg {
Normal,
Minimized,
Maximized,
Fullscreen,
Hidden,
}
impl From<StateArg> for WindowState {
fn from(arg: StateArg) -> Self {
match arg {
StateArg::Normal => WindowState::Normal,
StateArg::Minimized => WindowState::Minimized,
StateArg::Maximized => WindowState::Maximized,
StateArg::Fullscreen => WindowState::Fullscreen,
StateArg::Hidden => WindowState::Hidden,
}
}
}
fn main() {
let cli = Cli::parse();
if cli.verbose {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("debug"))
.init();
println!("🔍 Verbose mode enabled");
} else {
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"))
.init();
}
match &cli.command {
Some(Commands::Init { output }) => {
handle_init(output.clone());
}
Some(Commands::Validate) => {
handle_validate(cli.config);
}
Some(Commands::Info) => {
handle_info(cli.config);
}
Some(Commands::Gui { width, height }) => {
handle_gui(cli.config, cli.resource_mode.into(), *width, *height);
}
Some(Commands::Create { title, app_id, width, height, manifest }) => {
handle_create(cli.config, cli.resource_mode.into(), title, app_id, *width, *height, manifest.clone());
}
Some(Commands::List { detailed }) => {
handle_list(cli.config, cli.resource_mode.into(), *detailed);
}
Some(Commands::Close { window_id }) => {
handle_close(cli.config, cli.resource_mode.into(), *window_id);
}
Some(Commands::Focus { window_id }) => {
handle_focus(cli.config, cli.resource_mode.into(), *window_id);
}
Some(Commands::Resources { window_id }) => {
handle_resources(cli.config, cli.resource_mode.into(), *window_id);
}
Some(Commands::State { window_id, state }) => {
handle_state(cli.config, cli.resource_mode.into(), *window_id, state.clone().into());
}
Some(Commands::Cycle { count }) => {
handle_cycle(cli.config, cli.resource_mode.into(), *count);
}
Some(Commands::UClient { raw }) => {
handle_uclient(cli.config, *raw);
}
None => {
handle_gui(cli.config, cli.resource_mode.into(), 1200, 800);
}
}
}
fn handle_init(output: Option<String>) {
println!("🔧 Initializing WASMA configuration...");
match init_config(output) {
Ok(path) => {
println!("✅ Configuration file created: {}", path);
println!(" Edit this file to customize your WASMA setup.");
}
Err(e) => {
eprintln!("❌ Failed to initialize config: {}", e);
process::exit(1);
}
}
}
fn handle_validate(config_path: Option<String>) {
println!("🔍 Validating configuration...");
match validate_config(config_path) {
Ok(_) => {
println!("✅ Configuration is valid!");
}
Err(e) => {
eprintln!("❌ Configuration validation failed: {}", e);
process::exit(1);
}
}
}
fn handle_info(config_path: Option<String>) {
if let Err(e) = print_config_info(config_path) {
eprintln!("❌ Failed to read config: {}", e);
process::exit(1);
}
}
fn handle_gui(config_path: Option<String>, resource_mode: ResourceMode, _width: u32, _height: u32) {
println!("🖥️ Launching WASMA GUI Window Manager...");
let core = match build_core(config_path, Some(resource_mode)) {
Ok(c) => c,
Err(e) => {
eprintln!("❌ Failed to initialize WASMA Core: {}", e);
process::exit(1);
}
};
println!("🚀 Starting GUI with resource mode: {:?}", resource_mode);
if let Err(e) = core.launch_gui() {
eprintln!("❌ GUI failed: {}", e);
process::exit(1);
}
}
fn handle_create(
config_path: Option<String>,
resource_mode: ResourceMode,
title: &str,
app_id: &str,
width: u32,
height: u32,
manifest: Option<String>,
) {
let core = match build_core(config_path, Some(resource_mode)) {
Ok(c) => c,
Err(e) => {
eprintln!("❌ Failed to initialize WASMA Core: {}", e);
process::exit(1);
}
};
println!("🪟 Creating window: {}", title);
let result = if manifest.is_some() {
core.create_window(
title.to_string(),
app_id.to_string(),
width,
height,
)
} else {
core.create_window(
title.to_string(),
app_id.to_string(),
width,
height,
)
};
match result {
Ok(window_id) => {
println!("✅ Window created successfully!");
println!(" Window ID: {}", window_id);
println!(" Title: {}", title);
println!(" Size: {}x{}", width, height);
println!(" Mode: {:?}", resource_mode);
}
Err(e) => {
eprintln!("❌ Failed to create window: {}", e);
process::exit(1);
}
}
}
fn handle_list(config_path: Option<String>, resource_mode: ResourceMode, detailed: bool) {
let core = match build_core(config_path, Some(resource_mode)) {
Ok(c) => c,
Err(e) => {
eprintln!("❌ Failed to initialize WASMA Core: {}", e);
process::exit(1);
}
};
let windows = core.list_windows();
if windows.is_empty() {
println!("ℹ️ No active windows.");
return;
}
println!("╔════════════════════════════════════════════════════════════╗");
println!("║ Active Windows ║");
println!("╚════════════════════════════════════════════════════════════╝\n");
for window in &windows {
let state_icon = match window.state {
WindowState::Normal => "🟢",
WindowState::Minimized => "🟡",
WindowState::Maximized => "🔵",
WindowState::Fullscreen => "⚡",
WindowState::Hidden => "⚫",
};
let focus = if window.focused { "👁️ " } else { "" };
println!("{}{} Window #{}: {}", focus, state_icon, window.id, window.title);
println!(" App ID: {}", window.app_id);
println!(" Geometry: {}x{} at ({}, {})",
window.geometry.width,
window.geometry.height,
window.geometry.x,
window.geometry.y
);
println!(" Visible: {} | Focused: {}", window.visible, window.focused);
if detailed {
println!(" Renderer: {}", window.resource_limits.renderer);
println!(" Execution Mode: {:?}", window.resource_limits.execution_mode);
if let Ok(usage) = core.get_window_resources(window.id) {
println!(" RAM: {} MiB | VRAM: {} MiB",
usage.ram_allocated_mb,
usage.vram_allocated_mb
);
println!(" CPU Cores: {:?}", usage.cpu_cores);
if let Some(ref gpu) = usage.gpu_device {
println!(" GPU: {}", gpu);
}
println!(" Task Active: {} | GPU Active: {}",
usage.task_active,
usage.gpu_active
);
if usage.remaining_lease_secs > 0 {
println!(" Lease Remaining: {}s", usage.remaining_lease_secs);
}
}
}
println!();
}
println!("Total windows: {}", windows.len());
}
fn handle_close(config_path: Option<String>, resource_mode: ResourceMode, window_id: u64) {
let core = match build_core(config_path, Some(resource_mode)) {
Ok(c) => c,
Err(e) => {
eprintln!("❌ Failed to initialize WASMA Core: {}", e);
process::exit(1);
}
};
println!("🗑️ Closing window {}...", window_id);
match core.close_window(window_id) {
Ok(_) => {
println!("✅ Window {} closed successfully", window_id);
}
Err(e) => {
eprintln!("❌ Failed to close window: {}", e);
process::exit(1);
}
}
}
fn handle_focus(config_path: Option<String>, resource_mode: ResourceMode, window_id: u64) {
let core = match build_core(config_path, Some(resource_mode)) {
Ok(c) => c,
Err(e) => {
eprintln!("❌ Failed to initialize WASMA Core: {}", e);
process::exit(1);
}
};
println!("👁️ Focusing window {}...", window_id);
match core.focus_window(window_id) {
Ok(_) => {
println!("✅ Window {} is now focused", window_id);
}
Err(e) => {
eprintln!("❌ Failed to focus window: {}", e);
process::exit(1);
}
}
}
fn handle_resources(config_path: Option<String>, resource_mode: ResourceMode, window_id: u64) {
let core = match build_core(config_path, Some(resource_mode)) {
Ok(c) => c,
Err(e) => {
eprintln!("❌ Failed to initialize WASMA Core: {}", e);
process::exit(1);
}
};
match core.get_window_resources(window_id) {
Ok(usage) => {
println!("╔════════════════════════════════════════════════════════════╗");
println!("║ Window #{} Resource Usage ║", window_id);
println!("╚════════════════════════════════════════════════════════════╝\n");
println!("📊 Assignment ID: {}", usage.assignment_id);
println!("💾 RAM Allocated: {} MiB", usage.ram_allocated_mb);
println!("🎮 VRAM Allocated: {} MiB", usage.vram_allocated_mb);
println!("🔧 CPU Cores: {:?}", usage.cpu_cores);
if let Some(ref gpu) = usage.gpu_device {
println!("🎨 GPU Device: {}", gpu);
} else {
println!("🎨 GPU Device: None");
}
println!("⚙️ Execution Mode: {:?}", usage.execution_mode);
println!("🟢 Task Active: {}", usage.task_active);
println!("🎯 GPU Active: {}", usage.gpu_active);
if usage.remaining_lease_secs > 0 {
println!("⏱️ Lease Remaining: {}s", usage.remaining_lease_secs);
}
}
Err(e) => {
eprintln!("❌ Failed to get resources: {}", e);
process::exit(1);
}
}
}
fn handle_state(
config_path: Option<String>,
resource_mode: ResourceMode,
window_id: u64,
state: WindowState,
) {
let core = match build_core(config_path, Some(resource_mode)) {
Ok(c) => c,
Err(e) => {
eprintln!("❌ Failed to initialize WASMA Core: {}", e);
process::exit(1);
}
};
println!("🔄 Setting window {} state to {:?}...", window_id, state);
match core.set_window_state(window_id, state) {
Ok(_) => {
println!("✅ Window state changed successfully");
}
Err(e) => {
eprintln!("❌ Failed to change state: {}", e);
process::exit(1);
}
}
}
fn handle_cycle(config_path: Option<String>, resource_mode: ResourceMode, count: u32) {
let core = match build_core(config_path, Some(resource_mode)) {
Ok(c) => c,
Err(e) => {
eprintln!("❌ Failed to initialize WASMA Core: {}", e);
process::exit(1);
}
};
if count == 0 {
println!("🔄 Running resource management cycle continuously...");
println!(" Press Ctrl+C to stop");
loop {
core.update();
std::thread::sleep(std::time::Duration::from_secs(1));
}
} else {
println!("🔄 Running {} resource management cycle(s)...", count);
for i in 1..=count {
println!(" Cycle {}/{}", i, count);
core.update();
if i < count {
std::thread::sleep(std::time::Duration::from_millis(500));
}
}
println!("✅ Resource cycles completed");
}
}
fn handle_uclient(config_path: Option<String>, raw: bool) {
use wasma_client::{ConfigParser, uclient::UClient};
println!("🔌 Starting UClient engine...");
let parser = ConfigParser::new(config_path);
let mut config = match parser.load() {
Ok(c) => c,
Err(e) => {
eprintln!("❌ Failed to load config: {}", e);
process::exit(1);
}
};
if raw {
println!("⚡ Force enabling RAW mode (scope_level=0)");
config.resource_limits.scope_level = 0;
}
let mut client = UClient::new(config);
println!("🚀 UClient engine started");
if let Err(e) = client.start_engine() {
eprintln!("❌ UClient engine error: {}", e);
process::exit(1);
}
}
fn build_core(
config_path: Option<String>,
_resource_mode: Option<ResourceMode>,
) -> Result<WasmaCore, String> {
WasmaCore::new(config_path).map_err(|e| e.to_string())
}