# herolib-os

[![Crates.io](https://img.shields.io/crates/v/herolib-os.svg)](https://crates.io/crates/herolib-os)
[![Documentation](https://docs.rs/herolib-os/badge.svg)](https://docs.rs/herolib-os)

Unified system utilities for Rust and Rhai scripting, providing OS operations, process management, git, and network utilities.

## Documentation

- [API Documentation (docs.rs)](https://docs.rs/herolib-os)
- [Crates.io](https://crates.io/crates/herolib-os)

## Features

- **OS Module** - Filesystem operations, platform detection, package management, file downloads
- **Process Module** - Command execution with builder pattern, process management
- **Git Module** - Repository management, URL parsing, git tree organization
- **Network Module** - TCP connectivity, HTTP/HTTPS operations, SSH support with key management and file transfers
- **Profiling Module** - Cross-platform system profiling (network, disk, memory, CPU, monitoring, reporting)
- **Rhai Integration** - Full scripting support for all modules
- **Interactive REPL** - `hero-os` binary for testing and scripting

## Installation

Add to your `Cargo.toml`:

```toml
[dependencies]
herolib-os = "0.3.6"
```

### Feature Flags

| Feature | Description |
|---------|-------------|
| `rhai` | Rhai scripting support (default) |
| `repl` | Interactive REPL binary |
| `full` | All features enabled (rhai + repl) |

```toml
# Default (with Rhai scripting)
herolib-os = "0.3.6"

# With REPL support
herolib-os = { version = "0.3.6", features = ["repl"] }

# All features
herolib-os = { version = "0.3.6", features = ["full"] }
```

## Quick Start

### Rust API

```rust
use herolib_os::os::{exist, file_read, file_write};
use herolib_os::process::run;

fn main() -> anyhow::Result<()> {
    // Execute a command
    let result = run("ls -la")?;
    println!("Output: {}", result.stdout);

    // File operations
    if exist("/tmp/myfile.txt") {
        let content = file_read("/tmp/myfile.txt")?;
        println!("Content: {}", content);
    }

    file_write("/tmp/newfile.txt", "Hello, World!")?;

    Ok(())
}
```

### Rhai Scripting

```rhai
// Execute commands
let output = run("ls -la");
print(output);

// File operations
if exist("/tmp/myfile.txt") {
    let content = file_read("/tmp/myfile.txt");
    print(content);
}

// Platform detection
print("OS: " + os_name());
print("Arch: " + os_arch());

// TCP and HTTP connectivity checks
let is_open = net_tcp_check("example.com", 443);
let is_reachable = net_http_check("https://example.com");

// Network operations
let is_pingable = net_tcp_ping("example.com");
```

## Interactive REPL

Build and run the interactive REPL:

```bash
./build.sh
hero-os
```

REPL features:
- Tab completion for all functions
- Syntax highlighting
- Command history
- Script loading with `:load filename.rhai`
- Scope inspection with `:scope`

```
╔═══════════════════════════════════════════════════════════════════╗
║                         HERO-OS                                   ║
║               System Utilities REPL v0.1.0                        ║
╚═══════════════════════════════════════════════════════════════════╝

Type :help for available commands, :quit to exit

hero> run("uname -a")
Darwin myhost 24.6.0 Darwin Kernel Version 24.6.0 ...

hero> os_name()
macos

hero> /load rhaiexamples/os/01_filesystem.rhai
```

## Module Reference

### OS Module

| Function | Description |
|----------|-------------|
| `exist(path)` | Check if file/directory exists |
| `file_read(path)` | Read file contents |
| `file_write(path, content)` | Write content to file |
| `file_size(path)` | Get file size in bytes |
| `delete(path)` | Delete file or directory |
| `mkdir(path)` | Create directory |
| `copy(src, dest)` | Copy file or directory |
| `mv(src, dest)` | Move/rename file or directory |
| `os_name()` | Get OS name (linux, macos, windows) |
| `os_arch()` | Get architecture (x86_64, aarch64) |
| `which(cmd)` | Find command in PATH |
| `env_get(name)` | Get environment variable |
| `env_set(name, value)` | Set environment variable |

### Process Module

| Function | Description |
|----------|-------------|
| `run(cmd)` | Execute command, return stdout |
| `cmd(cmd)` | Create command builder |
| `process_list()` | List running processes |
| `process_get(pid)` | Get process by PID |
| `process_kill(pid)` | Kill process by PID |

**Command Builder Methods:**
```rhai
cmd("curl")
    .arg("-s")              // Add argument
    .args(["-H", "Accept: application/json"])
    .env("TOKEN", "xxx")    // Set environment variable
    .cwd("/tmp")            // Set working directory
    .silent()               // Suppress output
    .ignore_error()         // Don't fail on non-zero exit
    .execute()              // Run and return CommandResult
```

### Git Module

| Function | Description |
|----------|-------------|
| `parse_git_url_extended(url)` | Parse git URL into components |
| `git_tree_new(path)` | Create git tree manager |

**GitTree Methods:**
```rhai
let tree = git_tree_new("/repos");
tree.list()                    // List all repositories
tree.find("*pattern*")         // Find matching repos
tree.clone_repo(url)           // Clone repository
tree.get_path(url)             // Clone and return path
tree.get_path_pull(url)        // Clone, pull, return path
```

**GitRepo Methods:**
```rhai
repo.path()         // Get local path
repo.has_changes()  // Check for uncommitted changes
repo.pull()         // Pull from remote
repo.reset()        // Reset local changes
repo.commit(msg)    // Commit changes
repo.push()         // Push to remote
```

### Profiling Module

| Function | Description |
|----------|-------------|
| `SystemProfile()` | Get comprehensive system information (hostname, OS, CPU, memory, NUMA) |
| `measure_bandwidth(server, duration_sec)` | Measure network bandwidth (upload/download) |
| `measure_latency(host, count)` | Measure network latency with ping |
| `run_jitter_test(server)` | Test network jitter with UDP |
| `test_udp_throughput(server, bandwidth_bps)` | Test UDP throughput performance |
| `measure_sequential_read(path, size_bytes)` | Benchmark sequential disk reads |
| `measure_sequential_write(path, size_bytes)` | Benchmark sequential disk writes |
| `measure_random_read(path, size_bytes, block_size)` | Benchmark random disk reads |
| `measure_random_write(path, size_bytes, block_size)` | Benchmark random disk writes |
| `measure_iops(path)` | Measure disk IOPS performance |
| `test_disk_latency(path)` | Test disk latency percentiles |
| `measure_memory_bandwidth()` | Measure memory bandwidth (read/write/copy) |
| `test_memory_latency()` | Test memory access latency |
| `measure_cache_performance()` | Measure CPU cache performance |
| `test_numa_bandwidth()` | Test NUMA bandwidth performance |
| `run_memory_stress_test(duration_sec)` | Run memory stress test |
| `profile_memory_usage(pid)` | Profile memory usage of a process |
| `measure_single_thread_performance(duration_sec)` | Benchmark single-thread CPU performance |
| `measure_multi_thread_scaling(threads, duration_sec)` | Benchmark multi-thread scaling efficiency |
| `test_instruction_throughput()` | Test CPU instruction throughput |
| `measure_cache_misses()` | Measure CPU cache miss rates |
| `profile_cpu_usage(pid)` | Profile CPU usage of a process |
| `detect_thermal_state()` | Detect thermal throttling state (Linux/macOS) |
| `is_thermal_throttling()` | Simple check if CPU is throttling |
| `is_thermal_detection_supported()` | Check if thermal detection is available |
| `BenchmarkReport()` | Create new benchmark report |
| `generate_json(report)` | Generate JSON format report |
| `generate_text(report)` | Generate human-readable text report |
| `generate_html(report)` | Generate HTML format report |
| `ResourceMonitor(interval_sec)` | Create resource utilization monitor |
| `sample_cpu_utilization()` | Sample current CPU utilization |
| `sample_memory_usage()` | Sample current memory usage |
| `sample_io_wait_percent()` | Sample I/O wait percentage |
| `sample_io_queue_depth()` | Sample I/O queue depth |
| `analyze_trend(reports, metric)` | Analyze performance trend across multiple reports |
| `detect_regressions(reports, threshold)` | Detect performance regressions with severity |
| `calculate_statistics(reports)` | Calculate statistical summary of reports |
| `compare_reports(current, baseline)` | Compare two benchmark reports |

**Cross-Platform Examples:**
```rhai
// System profiling
let profile = SystemProfile();
print("System: " + profile.hostname + " (" + profile.os_name + " " + profile.os_version + ")");
print("CPU: " + profile.cpu_model + " (" + profile.cpu_cores + " cores, " + profile.cpu_threads + " threads)");
print("Memory: " + profile.memory_total_bytes + " bytes");

// Network benchmarking
let bandwidth = measure_bandwidth("iperf.example.com", 30);
print("Download: " + bandwidth.download_bps + " bps, Upload: " + bandwidth.upload_bps + " bps");

let latency = measure_latency("google.com", 10);
print("Latency: " + latency.avg_ms + "ms avg, " + latency.packet_loss_percent + "% loss");

// Disk benchmarking  
let disk_result = run_disk_benchmark("/tmp/test_file", 1024*1024*1024); // 1GB
print("Sequential read: " + disk_result.sequential_read.read_mb_per_sec + " MB/s");
print("Random IOPS: " + disk_result.iops.read_ops_per_sec + " ops/s");

// Memory benchmarking
let mem_result = run_memory_stress_test(60); // 60 seconds
print("Memory bandwidth: " + mem_result.read_bandwidth_gbps + " GB/s read");

// CPU benchmarking
let cpu_result = run_cpu_benchmark(4, std::time::Duration::from_secs(30));
print("Single thread: " + cpu_result.single_thread.integer_score + " points");
print("Multi thread efficiency: " + cpu_result.scaling.efficiency_percent + "%");

// Thermal throttling detection (Linux/macOS)
if is_thermal_detection_supported() {
    let thermal = detect_thermal_state();
    if thermal != () {
        print("Thermal state: " + thermal.severity);
        print("Throttling: " + thermal.is_throttling);
        if thermal.temperature_celsius != () {
            print("Temperature: " + thermal.temperature_celsius + "°C");
        }
    }
}

// NUMA detection (Linux/Windows)
let profile = SystemProfile();
if profile.numa_nodes != () {
    print("NUMA nodes: " + profile.numa_nodes);
}

// Resource monitoring
let monitor = ResourceMonitor(1); // 1 second interval
// ... run benchmarks ...
let report = monitor.stop();
print("Peak CPU: " + report.cpu_utilization.peak_percent + "%");
print("Peak memory: " + report.memory_utilization.peak_mb + " MB");

// Benchmark reports with metadata
let report = BenchmarkReport();
report.set_environment("production");
report.set_git_commit("abc123");
report.add_tag("region", "us-east-1");
print("Benchmark ID: " + report.benchmark_id);  // Auto-generated UUID
print("Timestamp: " + report.timestamp);        // Auto-generated timestamp

// Trend analysis across multiple reports
let reports = [];
reports.push(load_report_file("/history/report1.json"));
reports.push(load_report_file("/history/report2.json"));
reports.push(load_report_file("/history/report3.json"));

let trend = analyze_trend(reports, "cpu");
print("Trend: " + trend.direction);  // Improving/Degrading/Stable/Volatile
print("Mean: " + trend.mean);
print("Slope: " + trend.slope);

// Detect regressions (5% threshold)
let regressions = detect_regressions(reports, 5.0);
for regression in regressions {
    print("Regression in " + regression.metric + ": " + 
          regression.delta_percent + "% (" + regression.severity + ")");
}
```

#### Thermal Throttling Detection

Cross-platform thermal state detection with platform-specific details:

**Rust API:**
```rust
use herolib_os::profiling::cpu::{detect_thermal_state, ThermalSeverity};

match detect_thermal_state()? {
    Some(state) if state.is_throttling => {
        println!("⚠️  Throttling detected! Severity: {:?}", state.severity);
        
        // Linux-specific: Access temperature data
        if let Some(temp) = state.temperature_celsius {
            println!("Temperature: {:.1}°C", temp);
        }
        if let Some(zones) = &state.throttled_zones {
            println!("Throttled zones: {:?}", zones);
        }
    }
    Some(state) => {
        println!("✅ No throttling (severity: {:?})", state.severity);
    }
    None => {
        println!("ℹ️  Thermal detection not supported on this platform");
    }
}
```

**Platform Support:**
- **Linux:** Full support with temperature details, trip points, and zone information
- **macOS:** Supported with 4 thermal states (Normal/Light/Moderate/Critical)
- **Windows:** Not supported (returns `None`)

**Severity Levels:**
- `Normal` - No thermal pressure
- `Light` - System warming up, no throttling
- `Moderate` - Active throttling
- `Critical` - Severe throttling

#### NUMA Detection

Automatic NUMA node detection on supported platforms:

**Rust API:**
```rust
use herolib_os::profiling::system::SystemProfile;

let profile = SystemProfile::new();
if let Some(numa_nodes) = profile.numa_nodes {
    println!("NUMA nodes detected: {}", numa_nodes);
} else {
    println!("Single NUMA node or not detected");
}
```

**Platform Support:**
- **Linux:** Reads `/sys/devices/system/node/` (no privileges required)
- **macOS:** Returns `None` (Unified Memory Architecture)
- **Windows:** Uses `GetNumaHighestNodeNumber()` API (no privileges required)
```

### Network Module

| Function | Description |
|----------|-------------|
| `net_tcp_check(host, port)` | Check if a TCP port is open |
| `net_tcp_ping(host)` | Check if a host is reachable |
| `net_http_check(url)` | Check if a URL is reachable |
| `net_http_status(url)` | Get HTTP status code for a URL |

**SSH Connection:**
```rhai
let conn = SshConnection::new()
    .host("example.com")
    .user("ubuntu")
    .port(22)
    .connect();

let (code, output) = conn.execute("whoami");
```

**SSH Key Management:**
```rhai
let keygen = SshKeyGenerator::new("/tmp/my_key")
    .key_type(Ed25519);
keygen.generate();

let auth_mgr = AuthorizedKeysManager::new(conn);
auth_mgr.add_key("/path/to/id_rsa.pub");
```

**File Transfer (SSH/Rsync):**
```rhai
let transfer = FileTransferOps::new(conn);
transfer.upload("/local/file", "/remote/path");
transfer.download("/remote/file", "/local/path");
```

## Examples

See the `rhaiexamples/` directory for comprehensive examples:

```
rhaiexamples/
├── os/           # Filesystem, platform detection, package management
├── process/      # Command execution and process management
├── git/          # Repository management and URL handling
├── net/          # TCP, HTTP, and network connectivity
├── ssh/          # SSH connections and file transfer
└── profiling/    # System profiling and benchmarking (NEW!)
```

Run examples with the REPL:

```bash
hero-os rhaiexamples/os/01_filesystem.rhai
hero-os rhaiexamples/net/01_tcp_check.rhai
hero-os rhaiexamples/git/01_url_parsing.rhai
hero-os rhaiexamples/profiling/01_system_benchmark.rhai
hero-os rhaiexamples/profiling/02_quick_check.rhai
hero-os rhaiexamples/profiling/03_stress_test.rhai
```

## Building

```bash
# Build with REPL support
./build.sh

# Build with all features
cargo build --release --features full

# Build with cross-platform profiling support
cargo build --release --features "full,cross-platform"

# Run tests
cargo test

# Generate documentation
cargo doc --no-deps --open
```

## Requirements

- Rust 1.92.0 or later
- Edition 2024

### Optional Runtime Dependencies

- **Git** - For repository operations and cloning
- **SSH/OpenSSH** - For SSH operations and file transfers
- **curl** - For HTTP operations (recommended)
- **rsync** - For efficient SSH file transfers (recommended)

## License

Apache-2.0
