// Example demonstrating serialization and deserialization of Coords1D
//
// This example shows how to serialize Coords1D to JSON and deserialize it back,
// which is useful for saving and loading grid configurations.

use grid1d::coords::Coords1D;
use num_valid::RealNative64StrictFinite;
use sorted_vec::partial::SortedSet;
use try_create::TryNew;

fn main() {
    type Real = RealNative64StrictFinite;

    println!("=== Coords1D Serialization Example ===\n");

    // Create a Coords1D instance with some points
    let coords = Coords1D::try_from(SortedSet::from_unsorted(vec![
        Real::try_new(0.0).unwrap(),
        Real::try_new(2.5).unwrap(),
        Real::try_new(1.0).unwrap(),
        Real::try_new(5.0).unwrap(),
        Real::try_new(3.7).unwrap(),
    ]))
    .unwrap();

    println!("Original coordinates:");
    for (i, coord) in coords.iter().enumerate() {
        println!("  [{}] = {}", i, coord);
    }

    // Serialize to JSON
    let json = serde_json::to_string(&coords).unwrap();
    println!("\nSerialized to JSON:");
    println!("  {}", json);

    // Serialize to JSON with pretty formatting
    let json_pretty = serde_json::to_string_pretty(&coords).unwrap();
    println!("\nSerialized to JSON (pretty):");
    println!("{}", json_pretty);

    // Deserialize from JSON
    let deserialized: Coords1D<Real> = serde_json::from_str(&json).unwrap();
    println!("\nDeserialized coordinates:");
    for (i, coord) in deserialized.iter().enumerate() {
        println!("  [{}] = {}", i, coord);
    }

    // Verify they match
    assert_eq!(coords, deserialized);
    println!("\n✓ Coordinates match after round-trip serialization!");

    // Example: Save to file and load back
    println!("\n=== File I/O Example ===");

    let filename = "/tmp/coords1d_example.json";

    // Write to file
    std::fs::write(filename, json_pretty).unwrap();
    println!("\n✓ Saved coordinates to: {}", filename);

    // Read from file
    let json_from_file = std::fs::read_to_string(filename).unwrap();
    let coords_from_file: Coords1D<Real> = serde_json::from_str(&json_from_file).unwrap();

    println!("\n✓ Loaded coordinates from file:");
    for (i, coord) in coords_from_file.iter().enumerate() {
        println!("  [{}] = {}", i, coord);
    }

    assert_eq!(coords, coords_from_file);
    println!("\n✓ File I/O successful!");

    // Clean up
    std::fs::remove_file(filename).ok();

    // Example: Demonstrate error handling for empty arrays
    println!("\n=== Error Handling Example ===");

    let empty_json = "[]";
    let result: Result<Coords1D<Real>, _> = serde_json::from_str(empty_json);

    match result {
        Ok(_) => println!("✗ Unexpected success with empty array"),
        Err(e) => println!("✓ Correctly rejected empty array: {}", e),
    }

    println!("\n=== Example Complete ===");
}
