//! Example usage of the Runtime module for apps running inside BioLib containers.
//!
//! The Runtime module provides functions to interact with the BioLib runtime environment
//! when your code is executing inside a BioLib app container. These functions allow you to:
//! - Check if you're running inside a BioLib environment
//! - Access job metadata (ID, auth token, requested machine, etc.)
//! - Read secrets configured for your app
//! - Set result names and create notes
//! - Get OAuth tokens for external service integration

use biolib::Runtime;

fn main() {
    // Check if we're running inside a BioLib app container
    if !Runtime::check_is_environment_biolib_app() {
        println!("Not running inside a BioLib app - Runtime functions won't work");
        println!("Run this code inside a BioLib app container to use Runtime features");
        return;
    }

    example_get_job_info();
    example_set_result_name();
    example_read_secrets();
    example_create_note();
}

/// Get information about the current job
fn example_get_job_info() {
    // Get the current job ID
    let job_id = Runtime::get_job_id().expect("Failed to get job ID");
    println!("Current job ID: {job_id}");

    // Get the app URI that's being executed
    let app_uri = Runtime::get_app_uri().expect("Failed to get app URI");
    println!("Running app: {app_uri}");

    // Check if running in BioLib cloud (vs local execution)
    let is_cloud = Runtime::check_is_environment_biolib_cloud().unwrap_or(false);
    println!("Running in cloud: {is_cloud}");

    // Get the requested machine type (if specified by the user)
    if let Ok(Some(machine)) = Runtime::get_job_requested_machine() {
        println!("Requested machine: {machine}");
    }

    // Check if spot instance was requested
    let is_spot = Runtime::is_spot_machine_requested().unwrap_or(false);
    println!("Spot instance requested: {is_spot}");

    // Get max workers for parallel execution
    let max_workers = Runtime::get_max_workers().unwrap_or(1);
    println!("Max workers: {max_workers}");
}

/// Set the result name prefix for better organization
fn example_set_result_name() {
    // Set a custom result name prefix
    Runtime::set_main_result_prefix("my-analysis-result").expect("Failed to set result prefix");

    // Or use the alias
    Runtime::set_result_name_prefix("my-analysis-result").expect("Failed to set result prefix");

    // Set result name from a string (truncated to 60 chars)
    Runtime::set_result_name_from_string("Analysis of sample XYZ with parameters A=1, B=2")
        .expect("Failed to set result name");

    // Set result name from a file path
    // This extracts the filename and uses it as the result name
    Runtime::set_result_name_from_file("/input/my_sample.fasta")
        .expect("Failed to set result name from file");

    // For FASTA files, it can extract the first sequence ID
    // This is useful when the input file has a BioLib-generated name like "input_abc123.fasta"
    Runtime::set_result_name_prefix_from_fasta("/input/input_abc123.fasta")
        .expect("Failed to set result name from FASTA");
}

/// Read secrets configured for your app
fn example_read_secrets() {
    // Read a system secret (configured in the app settings)
    // These are secrets that the app developer has configured
    match Runtime::get_secret("API_KEY") {
        Ok(secret_bytes) => {
            let secret = String::from_utf8_lossy(&secret_bytes);
            println!("Got API key: {}...", &secret[..secret.len().min(4)]);
        }
        Err(err) => {
            println!("Could not read API_KEY secret: {err}");
        }
    }

    // Read a temporary client secret (provided by the user running the job)
    // These are secrets that users can provide when running the app
    match Runtime::get_temporary_client_secret("USER_TOKEN") {
        Ok(secret_bytes) => {
            let secret = String::from_utf8_lossy(&secret_bytes);
            println!("Got user token: {}...", &secret[..secret.len().min(4)]);
        }
        Err(err) => {
            println!("Could not read USER_TOKEN secret: {err}");
        }
    }
}

/// Create a note on the job result
fn example_create_note() {
    // Add a note to the job result
    // This is useful for adding metadata or status information
    Runtime::create_result_note("Analysis completed successfully with 95% confidence")
        .expect("Failed to create note");

    // Notes can include structured information
    Runtime::create_result_note("Parameters used: threshold=0.5, iterations=100")
        .expect("Failed to create note");
}

/// Get an OAuth access token for external service integration
fn _example_oauth_token() {
    // Request an OAuth token with a specific scope
    // This is useful for integrating with external services that support OAuth
    match Runtime::get_oauth_access_token("read:data write:results") {
        Ok(token) => {
            println!("Got OAuth token: {}...", &token[..token.len().min(10)]);
            // Use the token to authenticate with external services
        }
        Err(err) => {
            println!("Could not get OAuth token: {err}");
        }
    }
}

/// Get the job auth token for making authenticated API calls
fn _example_job_auth_token() {
    // Get the job-specific auth token
    // This can be used to make authenticated calls to the BioLib API
    let auth_token = Runtime::get_job_auth_token().expect("Failed to get auth token");
    println!(
        "Job auth token: {}...",
        &auth_token[..auth_token.len().min(10)]
    );
}
