/// Prints to [`stdout`][crate::stdout].
///
/// Equivalent to the [`println!`] macro except that a newline is not printed at
/// the end of the message.
///
/// Note that stdout is frequently line-buffered by default so it may be
/// necessary to use [`std::io::Write::flush()`] to ensure the output is emitted
/// immediately.
///
/// **NOTE:** The `print!` macro will lock the standard output on each call. If you call
/// `print!` within a hot loop, this behavior may be the bottleneck of the loop.
/// To avoid this, lock stdout with [`AutoStream::lock`][crate::AutoStream::lock]:
/// ```
/// #  #[cfg(feature = "auto")] {
/// use std::io::Write as _;
///
/// let mut lock = anstream::stdout().lock();
/// write!(lock, "hello world").unwrap();
/// # }
/// ```
///
/// Use `print!` only for the primary output of your program. Use
/// [`eprint!`] instead to print error and progress messages.
///
/// **NOTE:** Not all `print!` calls will be captured in tests like [`std::print!`]
/// - Capturing will automatically be activated in test binaries
/// - Otherwise, only when the `test` feature is enabled
///
/// # Panics
///
/// Panics if writing to `stdout` fails for any reason **except** broken pipe.
///
/// Writing to non-blocking stdout can cause an error, which will lead
/// this macro to panic.
///
/// # Examples
///
/// ```
/// #  #[cfg(feature = "auto")] {
/// use std::io::Write as _;
/// use anstream::print;
/// use anstream::stdout;
///
/// print!("this ");
/// print!("will ");
/// print!("be ");
/// print!("on ");
/// print!("the ");
/// print!("same ");
/// print!("line ");
///
/// stdout().flush().unwrap();
///
/// print!("this string has a newline, why not choose println! instead?\n");
///
/// stdout().flush().unwrap();
/// # }
/// ```
#[cfg(feature = "auto")]
#[macro_export]
macro_rules! print {
    ($($arg:tt)*) => {{
        if cfg!(any(feature = "test", test)) {
            use std::io::Write as _;

            let stdio = std::io::stdout();
            let choice = $crate::AutoStream::choice(&stdio);
            let buffer = Vec::new();
            let mut stream = $crate::AutoStream::new(buffer, choice);
            // Ignore errors rather than panic
            let _ = ::std::write!(&mut stream, $($arg)*);
            let buffer = stream.into_inner();
            // Should be UTF-8 but not wanting to panic
            let buffer = String::from_utf8_lossy(&buffer);
            ::std::print!("{}", buffer)
        } else {
            use std::io::Write as _;

            let mut stream = $crate::stdout();
            match ::std::write!(&mut stream, $($arg)*) {
                Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => {
                    ::std::panic!("failed printing to stdout: {e}");
                }
                Err(_) | Ok(_) => {}
            }
        }
    }};
}

/// Prints to [`stdout`][crate::stdout], with a newline.
///
/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
/// (no additional CARRIAGE RETURN (`\r`/`U+000D`)).
///
/// This macro uses the same syntax as [`format!`], but writes to the standard output instead.
/// See [`std::fmt`] for more information.
///
/// **NOTE:** The `println!` macro will lock the standard output on each call. If you call
/// `println!` within a hot loop, this behavior may be the bottleneck of the loop.
/// To avoid this, lock stdout with [`AutoStream::lock`][crate::AutoStream::lock]:
/// ```
/// #  #[cfg(feature = "auto")] {
/// use std::io::Write as _;
///
/// let mut lock = anstream::stdout().lock();
/// writeln!(lock, "hello world").unwrap();
/// # }
/// ```
///
/// Use `println!` only for the primary output of your program. Use
/// [`eprintln!`] instead to print error and progress messages.
///
/// **NOTE:** Not all `println!` calls will be captured in tests like [`std::println!`]
/// - Capturing will automatically be activated in test binaries
/// - Otherwise, only when the `test` feature is enabled
///
/// # Panics
///
/// Panics if writing to `stdout` fails for any reason **except** broken pipe.
///
/// Writing to non-blocking stdout can cause an error, which will lead
/// this macro to panic.
///
/// # Examples
///
/// ```
/// #  #[cfg(feature = "auto")] {
/// use anstream::println;
///
/// println!(); // prints just a newline
/// println!("hello there!");
/// println!("format {} arguments", "some");
/// let local_variable = "some";
/// println!("format {local_variable} arguments");
/// # }
/// ```
#[cfg(feature = "auto")]
#[macro_export]
macro_rules! println {
    () => {
        $crate::print!("\n")
    };
    ($($arg:tt)*) => {{
        if cfg!(any(feature = "test", test)) {
            use std::io::Write as _;

            let stdio = std::io::stdout();
            let choice = $crate::AutoStream::choice(&stdio);
            let buffer = Vec::new();
            let mut stream = $crate::AutoStream::new(buffer, choice);
            // Ignore errors rather than panic
            let _ = ::std::write!(&mut stream, $($arg)*);
            let buffer = stream.into_inner();
            // Should be UTF-8 but not wanting to panic
            let buffer = String::from_utf8_lossy(&buffer);
            ::std::println!("{}", buffer)
        } else {
            use std::io::Write as _;

            let mut stream = $crate::stdout();
            match ::std::writeln!(&mut stream, $($arg)*) {
                Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => {
                    ::std::panic!("failed printing to stdout: {e}");
                }
                Err(_) | Ok(_) => {}
            }
        }
    }};
}

/// Prints to [`stderr`][crate::stderr].
///
/// Equivalent to the [`print!`] macro, except that output goes to
/// `stderr` instead of `stdout`. See [`print!`] for
/// example usage.
///
/// Use `eprint!` only for error and progress messages. Use `print!`
/// instead for the primary output of your program.
///
/// **NOTE:** Not all `eprint!` calls will be captured in tests like [`std::eprint!`]
/// - Capturing will automatically be activated in test binaries
/// - Otherwise, only when the `test` feature is enabled
///
/// # Panics
///
/// Panics if writing to `stderr` fails for any reason **except** broken pipe.
///
/// Writing to non-blocking stdout can cause an error, which will lead
/// this macro to panic.
///
/// # Examples
///
/// ```
/// #  #[cfg(feature = "auto")] {
/// use anstream::eprint;
///
/// eprint!("Error: Could not complete task");
/// # }
/// ```
#[cfg(feature = "auto")]
#[macro_export]
macro_rules! eprint {
    ($($arg:tt)*) => {{
        if cfg!(any(feature = "test", test)) {
            use std::io::Write as _;

            let stdio = std::io::stderr();
            let choice = $crate::AutoStream::choice(&stdio);
            let buffer = Vec::new();
            let mut stream = $crate::AutoStream::new(buffer, choice);
            // Ignore errors rather than panic
            let _ = ::std::write!(&mut stream, $($arg)*);
            let buffer = stream.into_inner();
            // Should be UTF-8 but not wanting to panic
            let buffer = String::from_utf8_lossy(&buffer);
            ::std::eprint!("{}", buffer)
        } else {
            use std::io::Write as _;

            let mut stream = $crate::stderr();
            match ::std::write!(&mut stream, $($arg)*) {
                Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => {
                    ::std::panic!("failed printing to stdout: {e}");
                }
                Err(_) | Ok(_) => {}
            }
        }
    }};
}

/// Prints to [`stderr`][crate::stderr], with a newline.
///
/// Equivalent to the [`println!`] macro, except that output goes to
/// `stderr` instead of `stdout`. See [`println!`] for
/// example usage.
///
/// Use `eprintln!` only for error and progress messages. Use `println!`
/// instead for the primary output of your program.
///
/// **NOTE:** Not all `eprintln!` calls will be captured in tests like [`std::eprintln!`]
/// - Capturing will automatically be activated in test binaries
/// - Otherwise, only when the `test` feature is enabled
///
/// # Panics
///
/// Panics if writing to `stderr` fails for any reason **except** broken pipe.
///
/// Writing to non-blocking stdout can cause an error, which will lead
/// this macro to panic.
///
/// # Examples
///
/// ```
/// #  #[cfg(feature = "auto")] {
/// use anstream::eprintln;
///
/// eprintln!("Error: Could not complete task");
/// # }
/// ```
#[cfg(feature = "auto")]
#[macro_export]
macro_rules! eprintln {
    () => {
        $crate::eprint!("\n")
    };
    ($($arg:tt)*) => {{
        if cfg!(any(feature = "test", test)) {
            use std::io::Write as _;

            let stdio = std::io::stderr();
            let choice = $crate::AutoStream::choice(&stdio);
            let buffer = Vec::new();
            let mut stream = $crate::AutoStream::new(buffer, choice);
            // Ignore errors rather than panic
            let _ = ::std::write!(&mut stream, $($arg)*);
            let buffer = stream.into_inner();
            // Should be UTF-8 but not wanting to panic
            let buffer = String::from_utf8_lossy(&buffer);
            ::std::eprintln!("{}", buffer)
        } else {
            use std::io::Write as _;

            let mut stream = $crate::stderr();
            match ::std::writeln!(&mut stream, $($arg)*) {
                Err(e) if e.kind() != ::std::io::ErrorKind::BrokenPipe => {
                    ::std::panic!("failed printing to stdout: {e}");
                }
                Err(_) | Ok(_) => {}
            }
        }
    }};
}

/// Panics the current thread.
///
/// This allows a program to terminate immediately and provide feedback
/// to the caller of the program.
///
/// This macro is the perfect way to assert conditions in example code and in
/// tests. `panic!` is closely tied with the `unwrap` method of both
/// [`Option`][ounwrap] and [`Result`][runwrap] enums. Both implementations call
/// `panic!` when they are set to [`None`] or [`Err`] variants.
///
/// When using `panic!()` you can specify a string payload, that is built using
/// the [`format!`] syntax. That payload is used when injecting the panic into
/// the calling Rust thread, causing the thread to panic entirely.
///
/// The behavior of the default `std` hook, i.e. the code that runs directly
/// after the panic is invoked, is to print the message payload to
/// `stderr` along with the file/line/column information of the `panic!()`
/// call. You can override the panic hook using [`std::panic::set_hook()`].
/// Inside the hook a panic can be accessed as a `&dyn Any + Send`,
/// which contains either a `&str` or `String` for regular `panic!()` invocations.
/// To panic with a value of another other type, [`panic_any`] can be used.
///
/// See also the macro [`compile_error!`], for raising errors during compilation.
///
/// # When to use `panic!` vs `Result`
///
/// The Rust language provides two complementary systems for constructing /
/// representing, reporting, propagating, reacting to, and discarding errors. These
/// responsibilities are collectively known as "error handling." `panic!` and
/// `Result` are similar in that they are each the primary interface of their
/// respective error handling systems; however, the meaning these interfaces attach
/// to their errors and the responsibilities they fulfill within their respective
/// error handling systems differ.
///
/// The `panic!` macro is used to construct errors that represent a bug that has
/// been detected in your program. With `panic!` you provide a message that
/// describes the bug and the language then constructs an error with that message,
/// reports it, and propagates it for you.
///
/// `Result` on the other hand is used to wrap other types that represent either
/// the successful result of some computation, `Ok(T)`, or error types that
/// represent an anticipated runtime failure mode of that computation, `Err(E)`.
/// `Result` is used alongside user defined types which represent the various
/// anticipated runtime failure modes that the associated computation could
/// encounter. `Result` must be propagated manually, often with the the help of the
/// `?` operator and `Try` trait, and they must be reported manually, often with
/// the help of the `Error` trait.
///
/// For more detailed information about error handling check out the [book] or the
/// [`std::result`] module docs.
///
/// [ounwrap]: Option::unwrap
/// [runwrap]: Result::unwrap
/// [`std::panic::set_hook()`]: ../std/panic/fn.set_hook.html
/// [`panic_any`]: ../std/panic/fn.panic_any.html
/// [`Box`]: ../std/boxed/struct.Box.html
/// [`Any`]: crate::any::Any
/// [`format!`]: ../std/macro.format.html
/// [book]: ../book/ch09-00-error-handling.html
/// [`std::result`]: ../std/result/index.html
///
/// # Current implementation
///
/// If the main thread panics it will terminate all your threads and end your
/// program with code `101`.
///
/// # Examples
///
/// ```should_panic
/// # #![allow(unreachable_code)]
/// use anstream::panic;
/// panic!();
/// panic!("this is a terrible mistake!");
/// panic!("this is a {} {message}", "fancy", message = "message");
/// ```
#[cfg(feature = "auto")]
#[macro_export]
macro_rules! panic {
    () => {
        ::std::panic!()
    };
    ($($arg:tt)*) => {{
        use std::io::Write as _;

        let panic_stream = std::io::stderr();
        let choice = $crate::AutoStream::choice(&panic_stream);
        let buffer = Vec::new();
        let mut stream = $crate::AutoStream::new(buffer, choice);
        // Ignore errors rather than panic
        let _ = ::std::write!(&mut stream, $($arg)*);
        let buffer = stream.into_inner();
        // Should be UTF-8 but not wanting to panic
        let buffer = String::from_utf8_lossy(&buffer).into_owned();
        ::std::panic!("{}", buffer)
    }};
}
