# Library API

Documentation for using SRX as a Rust library.

---

## Installation

Add SRX to your `Cargo.toml`:

```toml
[dependencies]
srx = { git = "https://github.com/Jamshed-develop/srx.git" }
```

Or from Crates.io:

```toml
[dependencies]
srx = "1.0"
```

---

## Quick Start

### Pack a File

```rust
use srx::{Packer, compression::CompressionAlgo};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let packer = Packer::new("secure_password".to_string())
        .compression_algo(CompressionAlgo::Zstd)
        .compression_level(3);
    
    packer.pack("input.txt", "output.srx")?;
    
    println!("Archive created successfully!");
    Ok(())
}
```

### Unpack a File

```rust
use srx::Unpacker;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let unpacker = Unpacker::new("secure_password".to_string());
    unpacker.unpack("archive.srx")?;
    
    println!("File extracted successfully!");
    Ok(())
}
```

---

## API Reference

### `Packer`

The `Packer` struct is used to create encrypted archives.

#### Creating a Packer

```rust
use srx::Packer;

let packer = Packer::new("password".to_string());
```

#### Configuration Methods

| Method | Type | Default | Description |
|--------|------|---------|-------------|
| `compression_algo()` | `CompressionAlgo` | `Zstd` | Compression algorithm |
| `compression_level()` | `u8` | `3` | Compression level (0-22) |
| `chunk_size()` | `usize` | `262144` | Chunk size in bytes |
| `memory_limit()` | `u32` | `64` | Argon2 memory limit (MiB) |
| `parallelism()` | `u32` | `4` | Argon2 parallelism |

#### Methods

##### `pack()`

Create an archive from a file.

```rust
pub fn pack(&self, input_path: &str, output_path: &str) -> Result<(), SrxError>
```

**Parameters:**
- `input_path`: Path to the input file
- `output_path`: Path for the output archive

**Returns:**
- `Ok(())` on success
- `Err(SrxError)` on failure

**Example:**

```rust
packer.pack("document.pdf", "document.srx")?;
```

##### `pack_with_progress()`

Create an archive with progress callback.

```rust
pub fn pack_with_progress(
    &self,
    input_path: &str,
    output_path: &str,
    progress: impl Fn(Progress)
) -> Result<(), SrxError>
```

**Example:**

```rust
packer.pack_with_progress("large_file.bin", "large_file.srx", |p| {
    println!("Progress: {:.1}%", p.percent());
})?;
```

---

### `Unpacker`

The `Unpacker` struct is used to extract archives.

#### Creating an Unpacker

```rust
use srx::Unpacker;

let unpacker = Unpacker::new("password".to_string());
```

#### Methods

##### `unpack()`

Extract an archive to the current directory.

```rust
pub fn unpack(&self, input_path: &str) -> Result<(), SrxError>
```

**Example:**

```rust
unpacker.unpack("archive.srx")?;
```

##### `unpack_to()`

Extract an archive to a specific location.

```rust
pub fn unpack_to(&self, input_path: &str, output_path: &str) -> Result<(), SrxError>
```

**Example:**

```rust
unpacker.unpack_to("archive.srx", "/home/user/documents/")?;
```

##### `info()`

Get information about an archive.

```rust
pub fn info(&self, input_path: &str) -> Result<ArchiveInfo, SrxError>
```

**Returns:** `ArchiveInfo` struct with archive metadata.

**Example:**

```rust
let info = unpacker.info("archive.srx")?;
println!("Filename: {}", info.filename);
println!("Original size: {} bytes", info.original_size);
println!("Compressed size: {} bytes", info.compressed_size);
```

##### `verify()`

Verify archive integrity without extracting.

```rust
pub fn verify(&self, input_path: &str) -> Result<bool, SrxError>
```

**Example:**

```rust
if unpacker.verify("archive.srx")? {
    println!("Archive is valid!");
} else {
    println!("Archive is corrupted!");
}
```

---

### `ArchiveInfo`

Information about an archive.

```rust
pub struct ArchiveInfo {
    pub filename: String,
    pub original_size: u64,
    pub compressed_size: u64,
    pub chunk_count: u32,
    pub compression_algo: CompressionAlgo,
    pub encrypted: bool,
    pub created_at: Option<DateTime<Utc>>,
}
```

#### Fields

| Field | Type | Description |
|-------|------|-------------|
| `filename` | `String` | Original filename |
| `original_size` | `u64` | Size before compression |
| `compressed_size` | `u64` | Size after compression |
| `chunk_count` | `u32` | Number of chunks |
| `compression_algo` | `CompressionAlgo` | Compression algorithm used |
| `encrypted` | `bool` | Whether archive is encrypted |
| `created_at` | `Option<DateTime<Utc>>` | Creation timestamp |

#### Methods

##### `ratio()`

Calculate compression ratio.

```rust
pub fn ratio(&self) -> f64
```

**Example:**

```rust
let info = unpacker.info("archive.srx")?;
println!("Compression ratio: {:.1}%", info.ratio());
```

---

### `CompressionAlgo`

Compression algorithm enum.

```rust
pub enum CompressionAlgo {
    Zstd,
    Lz4,
    None,
}
```

#### Variants

| Variant | Description |
|---------|-------------|
| `Zstd` | Zstandard compression (default) |
| `Lz4` | LZ4 fast compression |
| `None` | No compression |

---

### `SrxError`

Error type for SRX operations.

```rust
pub enum SrxError {
    IoError(std::io::Error),
    CryptoError(String),
    InvalidPassword,
    CorruptedArchive,
    InvalidFormat,
    CompressionError(String),
    // ...
}
```

#### Common Variants

| Variant | Description |
|---------|-------------|
| `IoError` | File I/O error |
| `CryptoError` | Cryptographic operation failed |
| `InvalidPassword` | Wrong password provided |
| `CorruptedArchive` | Archive is corrupted or tampered |
| `InvalidFormat` | Not a valid SRX archive |
| `CompressionError` | Compression/decompression failed |

#### Error Handling

```rust
use srx::{Packer, SrxError};

match Packer::new("password".to_string()).pack("input.txt", "output.srx") {
    Ok(()) => println!("Success!"),
    Err(SrxError::IoError(e)) => eprintln!("I/O error: {}", e),
    Err(SrxError::InvalidPassword) => eprintln!("Wrong password!"),
    Err(SrxError::CorruptedArchive) => eprintln!("Archive is corrupted!"),
    Err(e) => eprintln!("Error: {}", e),
}
```

---

### `Progress`

Progress information for long operations.

```rust
pub struct Progress {
    pub bytes_processed: u64,
    pub total_bytes: u64,
    pub current_chunk: u32,
    pub total_chunks: u32,
}
```

#### Methods

##### `percent()`

Calculate completion percentage.

```rust
pub fn percent(&self) -> f64
```

**Example:**

```rust
packer.pack_with_progress("file.bin", "file.srx", |p| {
    print!("\rProgress: {:.1}%", p.percent());
})?;
```

---

## Advanced Usage

### Custom Configuration

```rust
use srx::{Packer, CompressionAlgo};

// Maximum compression for archival
let archive_packer = Packer::new("password".to_string())
    .compression_algo(CompressionAlgo::Zstd)
    .compression_level(19)
    .chunk_size(1024 * 1024);  // 1 MiB chunks

// Fast compression for backups
let backup_packer = Packer::new("password".to_string())
    .compression_algo(CompressionAlgo::Lz4)
    .chunk_size(128 * 1024);  // 128 KiB chunks

// No compression for pre-compressed data
let media_packer = Packer::new("password".to_string())
    .compression_algo(CompressionAlgo::None);
```

### Memory-Constrained Environment

```rust
use srx::Packer;

// Reduce memory usage for Argon2
let packer = Packer::new("password".to_string())
    .memory_limit(32)  // 32 MiB instead of default 64 MiB
    .parallelism(2);   // Reduce parallelism
```

### Streaming Large Files

```rust
use srx::{Packer, CompressionAlgo};

// Use smaller chunks for streaming
let packer = Packer::new("password".to_string())
    .chunk_size(64 * 1024);  // 64 KiB chunks

// Process large file with progress
packer.pack_with_progress("huge_file.tar", "huge_file.srx", |p| {
    eprintln!("Processing chunk {}/{}", p.current_chunk, p.total_chunks);
})?;
```

### Async Integration

SRX operations are blocking. Use with async runtimes:

```rust
use srx::Packer;
use tokio::task;

async fn pack_file(input: String, output: String, password: String) -> Result<(), Box<dyn std::error::Error>> {
    task::spawn_blocking(move || {
        Packer::new(password).pack(&input, &output)
    }).await??;
    
    Ok(())
}
```

---

## Working with Bytes

### Pack from Memory

```rust
use srx::{Packer, CompressionAlgo};

fn pack_bytes(data: &[u8], password: &str) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
    let packer = Packer::new(password.to_string())
        .compression_algo(CompressionAlgo::Zstd);
    
    let archive = packer.pack_bytes(data)?;
    Ok(archive)
}
```

### Unpack to Memory

```rust
use srx::Unpacker;

fn unpack_bytes(archive: &[u8], password: &str) -> Result<Vec<u8>, Box<dyn std::error::Error>> {
    let unpacker = Unpacker::new(password.to_string());
    let data = unpacker.unpack_bytes(archive)?;
    Ok(data)
}
```

---

## Thread Safety

SRX types are `Send` and can be used across threads:

```rust
use srx::Packer;
use std::thread;

let packer = Packer::new("password".to_string());

thread::spawn(move || {
    packer.pack("input.txt", "output.srx").unwrap();
});
```

---

## Feature Flags

SRX supports optional features in `Cargo.toml`:

```toml
[dependencies.srx]
version = "1.0"
features = ["parallel", "async"]
```

| Feature | Description |
|---------|-------------|
| `parallel` | Enable parallel compression (default) |
| `async` | Async API support |
| `json` | JSON output for info command |

---

## Examples

### Complete Example: Backup Tool

```rust
use srx::{Packer, Unpacker, CompressionAlgo, SrxError};
use std::path::Path;

fn backup_file(source: &Path, dest: &Path, password: &str) -> Result<(), SrxError> {
    let packer = Packer::new(password.to_string())
        .compression_algo(CompressionAlgo::Zstd)
        .compression_level(19);
    
    packer.pack(
        source.to_str().unwrap(),
        dest.to_str().unwrap()
    )?;
    
    println!("Backup created: {}", dest.display());
    Ok(())
}

fn restore_backup(archive: &Path, password: &str) -> Result<(), SrxError> {
    let unpacker = Unpacker::new(password.to_string());
    unpacker.unpack(archive.to_str().unwrap())?;
    
    println!("Backup restored!");
    Ok(())
}

fn main() {
    let args: Vec<String> = std::env::args().collect();
    
    match args[1].as_str() {
        "backup" => {
            backup_file(
                Path::new(&args[2]),
                Path::new(&args[3]),
                &args[4]
            ).unwrap();
        }
        "restore" => {
            restore_backup(Path::new(&args[2]), &args[3]).unwrap();
        }
        _ => eprintln!("Usage: {} backup|restore ...", args[0]),
    }
}
```

---

## See Also

- [CLI Reference](CLI-Reference) - Command-line interface
- [File Format](File-Format) - Archive format specification
- [Performance](Performance) - Optimization tips