/*!
This crate provides a cross platform abstraction for writing colored text to
a terminal. Colors are written using either ANSI escape sequences or by
communicating with a Windows console. Much of this API was motivated by use
inside command line applications, where colors or styles can be configured
by the end user and/or the environment.

This crate also provides platform independent support for writing colored text
to an in memory buffer. While this is easy to do with ANSI escape sequences
(because they are in the buffer themselves), it is trickier to do with the
Windows console API, which requires synchronous communication.

# Organization

The `WriteColor` trait extends the `io::Write` trait with methods for setting
colors or resetting them.

`StandardStream` and `StandardStreamLock` both satisfy `WriteColor` and are
analogous to `std::io::Stdout` and `std::io::StdoutLock`, or `std::io::Stderr`
and `std::io::StderrLock`.

`Buffer` is an in memory buffer that supports colored text. In a parallel
program, each thread might write to its own buffer. A buffer can be printed to
using a `BufferWriter`. The advantage of this design is that each thread can
work in parallel on a buffer without having to synchronize access to global
resources such as the Windows console. Moreover, this design also prevents
interleaving of buffer output.

`Ansi` and `NoColor` both satisfy `WriteColor` for arbitrary implementors of
`io::Write`. These types are useful when you know exactly what you need. An
analogous type for the Windows console is not provided since it cannot exist.

# Example: using `StandardStream`

The `StandardStream` type in this crate works similarly to `std::io::Stdout`,
except it is augmented with methods for coloring by the `WriteColor` trait.
For example, to write some green text:

```rust,no_run
# fn test() -> Result<(), Box<::std::error::Error>> {
use std::io::Write;
use termcolor::{Color, ColorChoice, ColorSpec, StandardStream, WriteColor};

let mut stdout = StandardStream::stdout(ColorChoice::Always);
stdout.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?;
writeln!(&mut stdout, "green text!")?;
# Ok(()) }
```

Note that any text written to the terminal now will be colored
green when using ANSI escape sequences, even if it is written via
stderr, and even if stderr had previously been set to `Color::Red`.
Users will need to manage any color changes themselves by calling
[`WriteColor::set_color`](trait.WriteColor.html#tymethod.set_color), and this
may include calling [`WriteColor::reset`](trait.WriteColor.html#tymethod.reset)
before the program exits to a shell.

# Example: using `BufferWriter`

A `BufferWriter` can create buffers and write buffers to stdout or stderr. It
does *not* implement `io::Write` or `WriteColor` itself. Instead, `Buffer`
implements `io::Write` and `io::WriteColor`.

This example shows how to print some green text to stderr.

```rust,no_run
# fn test() -> Result<(), Box<::std::error::Error>> {
use std::io::Write;
use termcolor::{BufferWriter, Color, ColorChoice, ColorSpec, WriteColor};

let mut bufwtr = BufferWriter::stderr(ColorChoice::Always);
let mut buffer = bufwtr.buffer();
buffer.set_color(ColorSpec::new().set_fg(Some(Color::Green)))?;
writeln!(&mut buffer, "green text!")?;
bufwtr.print(&buffer)?;
# Ok(()) }
```

# Detecting presence of a terminal

In many scenarios when using color, one often wants to enable colors
automatically when writing to a terminal and disable colors automatically when
writing to anything else. The typical way to achieve this in Unix environments
is via libc's
[`isatty`](http://man7.org/linux/man-pages/man3/isatty.3.html)
function.
Unfortunately, this notoriously does not work well in Windows environments. To
work around that, the currently recommended solution is to use the
[`atty`](https://crates.io/crates/atty)
crate, which goes out of its way to get this as right as possible in Windows
environments.

For example, in a command line application that exposes a `--color` flag,
your logic for how to enable colors might look like this:

```rust,ignore
use atty;
use termcolor::{ColorChoice, StandardStream};

let preference = argv.get_flag("color").unwrap_or("auto");
let choice = match preference {
    "always" => ColorChoice::Always,
    "ansi" => ColorChoice::AlwaysAnsi,
    "auto" => {
        if atty::is(atty::Stream::Stdout) {
            ColorChoice::Auto
        } else {
            ColorChoice::Never
        }
    }
    _ => ColorChoice::Never,
};
let stdout = StandardStream::stdout(choice);
// ... write to stdout
```

Currently, `termcolor` does not provide anything to do this for you.
*/

#![deny(missing_docs)]

// #[cfg(doctest)]
// use doc_comment::doctest;
// #[cfg(doctest)]
// doctest!("../README.md");

use std::env;
use std::error;
use std::fmt;
use std::io::{self, Write};
use std::str::FromStr;
use std::sync::atomic::{AtomicBool, Ordering};
#[cfg(windows)]
use std::sync::{Mutex, MutexGuard};

#[cfg(windows)]
use winapi_util::console as wincon;

/// This trait describes the behavior of writers that support colored output.
pub trait WriteColor: io::Write {
    /// Returns true if and only if the underlying writer supports colors.
    fn supports_color(&self) -> bool;

    /// Set the color settings of the writer.
    ///
    /// Subsequent writes to this writer will use these settings until either
    /// `reset` is called or new color settings are set.
    ///
    /// If there was a problem setting the color settings, then an error is
    /// returned.
    fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()>;

    /// Reset the current color settings to their original settings.
    ///
    /// If there was a problem resetting the color settings, then an error is
    /// returned.
    fn reset(&mut self) -> io::Result<()>;

    /// Returns true if and only if the underlying writer must synchronously
    /// interact with an end user's device in order to control colors. By
    /// default, this always returns `false`.
    ///
    /// In practice, this should return `true` if the underlying writer is
    /// manipulating colors using the Windows console APIs.
    ///
    /// This is useful for writing generic code (such as a buffered writer)
    /// that can perform certain optimizations when the underlying writer
    /// doesn't rely on synchronous APIs. For example, ANSI escape sequences
    /// can be passed through to the end user's device as is.
    fn is_synchronous(&self) -> bool {
        false
    }
}

impl<'a, T: ?Sized + WriteColor> WriteColor for &'a mut T {
    fn supports_color(&self) -> bool {
        (&**self).supports_color()
    }
    fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
        (&mut **self).set_color(spec)
    }
    fn reset(&mut self) -> io::Result<()> {
        (&mut **self).reset()
    }
    fn is_synchronous(&self) -> bool {
        (&**self).is_synchronous()
    }
}

impl<T: ?Sized + WriteColor> WriteColor for Box<T> {
    fn supports_color(&self) -> bool {
        (&**self).supports_color()
    }
    fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
        (&mut **self).set_color(spec)
    }
    fn reset(&mut self) -> io::Result<()> {
        (&mut **self).reset()
    }
    fn is_synchronous(&self) -> bool {
        (&**self).is_synchronous()
    }
}

/// ColorChoice represents the color preferences of an end user.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum ColorChoice {
    /// Try very hard to emit colors. This includes emitting ANSI colors
    /// on Windows if the console API is unavailable.
    Always,
    /// AlwaysAnsi is like Always, except it never tries to use anything other
    /// than emitting ANSI color codes.
    AlwaysAnsi,
    /// Try to use colors, but don't force the issue. If the console isn't
    /// available on Windows, or if TERM=dumb, or if `NO_COLOR` is defined, for
    /// example, then don't use colors.
    Auto,
    /// Never emit colors.
    Never,
}

impl ColorChoice {
    /// Returns true if we should attempt to write colored output.
    fn should_attempt_color(&self) -> bool {
        match *self {
            ColorChoice::Always => true,
            ColorChoice::AlwaysAnsi => true,
            ColorChoice::Never => false,
            ColorChoice::Auto => self.env_allows_color(),
        }
    }

    #[cfg(not(windows))]
    fn env_allows_color(&self) -> bool {
        match env::var_os("TERM") {
            // If TERM isn't set, then we are in a weird environment that
            // probably doesn't support colors.
            None => return false,
            Some(k) => {
                if k == "dumb" {
                    return false;
                }
            }
        }
        // If TERM != dumb, then the only way we don't allow colors at this
        // point is if NO_COLOR is set.
        if env::var_os("NO_COLOR").is_some() {
            return false;
        }
        true
    }

    #[cfg(windows)]
    fn env_allows_color(&self) -> bool {
        // On Windows, if TERM isn't set, then we shouldn't automatically
        // assume that colors aren't allowed. This is unlike Unix environments
        // where TERM is more rigorously set.
        if let Some(k) = env::var_os("TERM") {
            if k == "dumb" {
                return false;
            }
        }
        // If TERM != dumb, then the only way we don't allow colors at this
        // point is if NO_COLOR is set.
        if env::var_os("NO_COLOR").is_some() {
            return false;
        }
        true
    }

    /// Returns true if this choice should forcefully use ANSI color codes.
    ///
    /// It's possible that ANSI is still the correct choice even if this
    /// returns false.
    #[cfg(windows)]
    fn should_ansi(&self) -> bool {
        match *self {
            ColorChoice::Always => false,
            ColorChoice::AlwaysAnsi => true,
            ColorChoice::Never => false,
            ColorChoice::Auto => {
                match env::var("TERM") {
                    Err(_) => false,
                    // cygwin doesn't seem to support ANSI escape sequences
                    // and instead has its own variety. However, the Windows
                    // console API may be available.
                    Ok(k) => k != "dumb" && k != "cygwin",
                }
            }
        }
    }
}

/// `std::io` implements `Stdout` and `Stderr` (and their `Lock` variants) as
/// separate types, which makes it difficult to abstract over them. We use
/// some simple internal enum types to work around this.

enum StandardStreamType {
    Stdout,
    Stderr,
    StdoutBuffered,
    StderrBuffered,
}

enum IoStandardStream {
    Stdout(io::Stdout),
    Stderr(io::Stderr),
    StdoutBuffered(io::BufWriter<io::Stdout>),
    StderrBuffered(io::BufWriter<io::Stderr>),
}

impl IoStandardStream {
    fn new(sty: StandardStreamType) -> IoStandardStream {
        match sty {
            StandardStreamType::Stdout => {
                IoStandardStream::Stdout(io::stdout())
            }
            StandardStreamType::Stderr => {
                IoStandardStream::Stderr(io::stderr())
            }
            StandardStreamType::StdoutBuffered => {
                let wtr = io::BufWriter::new(io::stdout());
                IoStandardStream::StdoutBuffered(wtr)
            }
            StandardStreamType::StderrBuffered => {
                let wtr = io::BufWriter::new(io::stderr());
                IoStandardStream::StderrBuffered(wtr)
            }
        }
    }

    fn lock(&self) -> IoStandardStreamLock<'_> {
        match *self {
            IoStandardStream::Stdout(ref s) => {
                IoStandardStreamLock::StdoutLock(s.lock())
            }
            IoStandardStream::Stderr(ref s) => {
                IoStandardStreamLock::StderrLock(s.lock())
            }
            IoStandardStream::StdoutBuffered(_)
            | IoStandardStream::StderrBuffered(_) => {
                // We don't permit this case to ever occur in the public API,
                // so it's OK to panic.
                panic!("cannot lock a buffered standard stream")
            }
        }
    }
}

impl io::Write for IoStandardStream {
    #[inline(always)]
    fn write(&mut self, b: &[u8]) -> io::Result<usize> {
        match *self {
            IoStandardStream::Stdout(ref mut s) => s.write(b),
            IoStandardStream::Stderr(ref mut s) => s.write(b),
            IoStandardStream::StdoutBuffered(ref mut s) => s.write(b),
            IoStandardStream::StderrBuffered(ref mut s) => s.write(b),
        }
    }

    #[inline(always)]
    fn flush(&mut self) -> io::Result<()> {
        match *self {
            IoStandardStream::Stdout(ref mut s) => s.flush(),
            IoStandardStream::Stderr(ref mut s) => s.flush(),
            IoStandardStream::StdoutBuffered(ref mut s) => s.flush(),
            IoStandardStream::StderrBuffered(ref mut s) => s.flush(),
        }
    }
}

// Same rigmarole for the locked variants of the standard streams.

enum IoStandardStreamLock<'a> {
    StdoutLock(io::StdoutLock<'a>),
    StderrLock(io::StderrLock<'a>),
}

impl<'a> io::Write for IoStandardStreamLock<'a> {
    #[inline(always)]
    fn write(&mut self, b: &[u8]) -> io::Result<usize> {
        match *self {
            IoStandardStreamLock::StdoutLock(ref mut s) => s.write(b),
            IoStandardStreamLock::StderrLock(ref mut s) => s.write(b),
        }
    }

    #[inline(always)]
    fn flush(&mut self) -> io::Result<()> {
        match *self {
            IoStandardStreamLock::StdoutLock(ref mut s) => s.flush(),
            IoStandardStreamLock::StderrLock(ref mut s) => s.flush(),
        }
    }
}

/// Satisfies `io::Write` and `WriteColor`, and supports optional coloring
/// to either of the standard output streams, stdout and stderr.
pub struct StandardStream {
    wtr: LossyStandardStream<WriterInner<IoStandardStream>>,
}

/// `StandardStreamLock` is a locked reference to a `StandardStream`.
///
/// This implements the `io::Write` and `WriteColor` traits, and is constructed
/// via the `Write::lock` method.
///
/// The lifetime `'a` refers to the lifetime of the corresponding
/// `StandardStream`.
pub struct StandardStreamLock<'a> {
    wtr: LossyStandardStream<WriterInnerLock<'a, IoStandardStreamLock<'a>>>,
}

/// Like `StandardStream`, but does buffered writing.
pub struct BufferedStandardStream {
    wtr: LossyStandardStream<WriterInner<IoStandardStream>>,
}

/// WriterInner is a (limited) generic representation of a writer. It is
/// limited because W should only ever be stdout/stderr on Windows.
enum WriterInner<W> {
    NoColor(NoColor<W>),
    Ansi(Ansi<W>),
    #[cfg(windows)]
    Windows {
        wtr: W,
        console: Mutex<wincon::Console>,
    },
}

/// WriterInnerLock is a (limited) generic representation of a writer. It is
/// limited because W should only ever be stdout/stderr on Windows.
enum WriterInnerLock<'a, W> {
    NoColor(NoColor<W>),
    Ansi(Ansi<W>),
    /// What a gross hack. On Windows, we need to specify a lifetime for the
    /// console when in a locked state, but obviously don't need to do that
    /// on Unix, which makes the `'a` unused. To satisfy the compiler, we need
    /// a PhantomData.
    #[allow(dead_code)]
    Unreachable(::std::marker::PhantomData<&'a ()>),
    #[cfg(windows)]
    Windows {
        wtr: W,
        console: MutexGuard<'a, wincon::Console>,
    },
}

impl StandardStream {
    /// Create a new `StandardStream` with the given color preferences that
    /// writes to standard output.
    ///
    /// On Windows, if coloring is desired and a Windows console could not be
    /// found, then ANSI escape sequences are used instead.
    ///
    /// The specific color/style settings can be configured when writing via
    /// the `WriteColor` trait.
    pub fn stdout(choice: ColorChoice) -> StandardStream {
        let wtr = WriterInner::create(StandardStreamType::Stdout, choice);
        StandardStream { wtr: LossyStandardStream::new(wtr) }
    }

    /// Create a new `StandardStream` with the given color preferences that
    /// writes to standard error.
    ///
    /// On Windows, if coloring is desired and a Windows console could not be
    /// found, then ANSI escape sequences are used instead.
    ///
    /// The specific color/style settings can be configured when writing via
    /// the `WriteColor` trait.
    pub fn stderr(choice: ColorChoice) -> StandardStream {
        let wtr = WriterInner::create(StandardStreamType::Stderr, choice);
        StandardStream { wtr: LossyStandardStream::new(wtr) }
    }

    /// Lock the underlying writer.
    ///
    /// The lock guard returned also satisfies `io::Write` and
    /// `WriteColor`.
    ///
    /// This method is **not reentrant**. It may panic if `lock` is called
    /// while a `StandardStreamLock` is still alive.
    pub fn lock(&self) -> StandardStreamLock<'_> {
        StandardStreamLock::from_stream(self)
    }
}

impl<'a> StandardStreamLock<'a> {
    #[cfg(not(windows))]
    fn from_stream(stream: &StandardStream) -> StandardStreamLock<'_> {
        let locked = match *stream.wtr.get_ref() {
            WriterInner::NoColor(ref w) => {
                WriterInnerLock::NoColor(NoColor(w.0.lock()))
            }
            WriterInner::Ansi(ref w) => {
                WriterInnerLock::Ansi(Ansi(w.0.lock()))
            }
        };
        StandardStreamLock { wtr: stream.wtr.wrap(locked) }
    }

    #[cfg(windows)]
    fn from_stream(stream: &StandardStream) -> StandardStreamLock {
        let locked = match *stream.wtr.get_ref() {
            WriterInner::NoColor(ref w) => {
                WriterInnerLock::NoColor(NoColor(w.0.lock()))
            }
            WriterInner::Ansi(ref w) => {
                WriterInnerLock::Ansi(Ansi(w.0.lock()))
            }
            #[cfg(windows)]
            WriterInner::Windows { ref wtr, ref console } => {
                WriterInnerLock::Windows {
                    wtr: wtr.lock(),
                    console: console.lock().unwrap(),
                }
            }
        };
        StandardStreamLock { wtr: stream.wtr.wrap(locked) }
    }
}

impl BufferedStandardStream {
    /// Create a new `BufferedStandardStream` with the given color preferences
    /// that writes to standard output via a buffered writer.
    ///
    /// On Windows, if coloring is desired and a Windows console could not be
    /// found, then ANSI escape sequences are used instead.
    ///
    /// The specific color/style settings can be configured when writing via
    /// the `WriteColor` trait.
    pub fn stdout(choice: ColorChoice) -> BufferedStandardStream {
        let wtr =
            WriterInner::create(StandardStreamType::StdoutBuffered, choice);
        BufferedStandardStream { wtr: LossyStandardStream::new(wtr) }
    }

    /// Create a new `BufferedStandardStream` with the given color preferences
    /// that writes to standard error via a buffered writer.
    ///
    /// On Windows, if coloring is desired and a Windows console could not be
    /// found, then ANSI escape sequences are used instead.
    ///
    /// The specific color/style settings can be configured when writing via
    /// the `WriteColor` trait.
    pub fn stderr(choice: ColorChoice) -> BufferedStandardStream {
        let wtr =
            WriterInner::create(StandardStreamType::StderrBuffered, choice);
        BufferedStandardStream { wtr: LossyStandardStream::new(wtr) }
    }
}

impl WriterInner<IoStandardStream> {
    /// Create a new inner writer for a standard stream with the given color
    /// preferences.
    #[cfg(not(windows))]
    fn create(
        sty: StandardStreamType,
        choice: ColorChoice,
    ) -> WriterInner<IoStandardStream> {
        if choice.should_attempt_color() {
            WriterInner::Ansi(Ansi(IoStandardStream::new(sty)))
        } else {
            WriterInner::NoColor(NoColor(IoStandardStream::new(sty)))
        }
    }

    /// Create a new inner writer for a standard stream with the given color
    /// preferences.
    ///
    /// If coloring is desired and a Windows console could not be found, then
    /// ANSI escape sequences are used instead.
    #[cfg(windows)]
    fn create(
        sty: StandardStreamType,
        choice: ColorChoice,
    ) -> WriterInner<IoStandardStream> {
        let mut con = match sty {
            StandardStreamType::Stdout => wincon::Console::stdout(),
            StandardStreamType::Stderr => wincon::Console::stderr(),
            StandardStreamType::StdoutBuffered => wincon::Console::stdout(),
            StandardStreamType::StderrBuffered => wincon::Console::stderr(),
        };
        let is_console_virtual = con
            .as_mut()
            .map(|con| con.set_virtual_terminal_processing(true).is_ok())
            .unwrap_or(false);
        if choice.should_attempt_color() {
            if choice.should_ansi() || is_console_virtual {
                WriterInner::Ansi(Ansi(IoStandardStream::new(sty)))
            } else if let Ok(console) = con {
                WriterInner::Windows {
                    wtr: IoStandardStream::new(sty),
                    console: Mutex::new(console),
                }
            } else {
                WriterInner::Ansi(Ansi(IoStandardStream::new(sty)))
            }
        } else {
            WriterInner::NoColor(NoColor(IoStandardStream::new(sty)))
        }
    }
}

impl io::Write for StandardStream {
    #[inline]
    fn write(&mut self, b: &[u8]) -> io::Result<usize> {
        self.wtr.write(b)
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        self.wtr.flush()
    }
}

impl WriteColor for StandardStream {
    #[inline]
    fn supports_color(&self) -> bool {
        self.wtr.supports_color()
    }

    #[inline]
    fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
        self.wtr.set_color(spec)
    }

    #[inline]
    fn reset(&mut self) -> io::Result<()> {
        self.wtr.reset()
    }

    #[inline]
    fn is_synchronous(&self) -> bool {
        self.wtr.is_synchronous()
    }
}

impl<'a> io::Write for StandardStreamLock<'a> {
    #[inline]
    fn write(&mut self, b: &[u8]) -> io::Result<usize> {
        self.wtr.write(b)
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        self.wtr.flush()
    }
}

impl<'a> WriteColor for StandardStreamLock<'a> {
    #[inline]
    fn supports_color(&self) -> bool {
        self.wtr.supports_color()
    }

    #[inline]
    fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
        self.wtr.set_color(spec)
    }

    #[inline]
    fn reset(&mut self) -> io::Result<()> {
        self.wtr.reset()
    }

    #[inline]
    fn is_synchronous(&self) -> bool {
        self.wtr.is_synchronous()
    }
}

impl io::Write for BufferedStandardStream {
    #[inline]
    fn write(&mut self, b: &[u8]) -> io::Result<usize> {
        self.wtr.write(b)
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        self.wtr.flush()
    }
}

impl WriteColor for BufferedStandardStream {
    #[inline]
    fn supports_color(&self) -> bool {
        self.wtr.supports_color()
    }

    #[inline]
    fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
        if self.is_synchronous() {
            self.wtr.flush()?;
        }
        self.wtr.set_color(spec)
    }

    #[inline]
    fn reset(&mut self) -> io::Result<()> {
        self.wtr.reset()
    }

    #[inline]
    fn is_synchronous(&self) -> bool {
        self.wtr.is_synchronous()
    }
}

impl<W: io::Write> io::Write for WriterInner<W> {
    #[inline(always)]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        match *self {
            WriterInner::NoColor(ref mut wtr) => wtr.write(buf),
            WriterInner::Ansi(ref mut wtr) => wtr.write(buf),
            #[cfg(windows)]
            WriterInner::Windows { ref mut wtr, .. } => wtr.write(buf),
        }
    }

    #[inline(always)]
    fn flush(&mut self) -> io::Result<()> {
        match *self {
            WriterInner::NoColor(ref mut wtr) => wtr.flush(),
            WriterInner::Ansi(ref mut wtr) => wtr.flush(),
            #[cfg(windows)]
            WriterInner::Windows { ref mut wtr, .. } => wtr.flush(),
        }
    }
}

impl<W: io::Write> WriteColor for WriterInner<W> {
    fn supports_color(&self) -> bool {
        match *self {
            WriterInner::NoColor(_) => false,
            WriterInner::Ansi(_) => true,
            #[cfg(windows)]
            WriterInner::Windows { .. } => true,
        }
    }

    fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
        match *self {
            WriterInner::NoColor(ref mut wtr) => wtr.set_color(spec),
            WriterInner::Ansi(ref mut wtr) => wtr.set_color(spec),
            #[cfg(windows)]
            WriterInner::Windows { ref mut wtr, ref console } => {
                wtr.flush()?;
                let mut console = console.lock().unwrap();
                spec.write_console(&mut *console)
            }
        }
    }

    fn reset(&mut self) -> io::Result<()> {
        match *self {
            WriterInner::NoColor(ref mut wtr) => wtr.reset(),
            WriterInner::Ansi(ref mut wtr) => wtr.reset(),
            #[cfg(windows)]
            WriterInner::Windows { ref mut wtr, ref mut console } => {
                wtr.flush()?;
                console.lock().unwrap().reset()?;
                Ok(())
            }
        }
    }

    fn is_synchronous(&self) -> bool {
        match *self {
            WriterInner::NoColor(_) => false,
            WriterInner::Ansi(_) => false,
            #[cfg(windows)]
            WriterInner::Windows { .. } => true,
        }
    }
}

impl<'a, W: io::Write> io::Write for WriterInnerLock<'a, W> {
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        match *self {
            WriterInnerLock::Unreachable(_) => unreachable!(),
            WriterInnerLock::NoColor(ref mut wtr) => wtr.write(buf),
            WriterInnerLock::Ansi(ref mut wtr) => wtr.write(buf),
            #[cfg(windows)]
            WriterInnerLock::Windows { ref mut wtr, .. } => wtr.write(buf),
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        match *self {
            WriterInnerLock::Unreachable(_) => unreachable!(),
            WriterInnerLock::NoColor(ref mut wtr) => wtr.flush(),
            WriterInnerLock::Ansi(ref mut wtr) => wtr.flush(),
            #[cfg(windows)]
            WriterInnerLock::Windows { ref mut wtr, .. } => wtr.flush(),
        }
    }
}

impl<'a, W: io::Write> WriteColor for WriterInnerLock<'a, W> {
    fn supports_color(&self) -> bool {
        match *self {
            WriterInnerLock::Unreachable(_) => unreachable!(),
            WriterInnerLock::NoColor(_) => false,
            WriterInnerLock::Ansi(_) => true,
            #[cfg(windows)]
            WriterInnerLock::Windows { .. } => true,
        }
    }

    fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
        match *self {
            WriterInnerLock::Unreachable(_) => unreachable!(),
            WriterInnerLock::NoColor(ref mut wtr) => wtr.set_color(spec),
            WriterInnerLock::Ansi(ref mut wtr) => wtr.set_color(spec),
            #[cfg(windows)]
            WriterInnerLock::Windows { ref mut wtr, ref mut console } => {
                wtr.flush()?;
                spec.write_console(console)
            }
        }
    }

    fn reset(&mut self) -> io::Result<()> {
        match *self {
            WriterInnerLock::Unreachable(_) => unreachable!(),
            WriterInnerLock::NoColor(ref mut wtr) => wtr.reset(),
            WriterInnerLock::Ansi(ref mut wtr) => wtr.reset(),
            #[cfg(windows)]
            WriterInnerLock::Windows { ref mut wtr, ref mut console } => {
                wtr.flush()?;
                console.reset()?;
                Ok(())
            }
        }
    }

    fn is_synchronous(&self) -> bool {
        match *self {
            WriterInnerLock::Unreachable(_) => unreachable!(),
            WriterInnerLock::NoColor(_) => false,
            WriterInnerLock::Ansi(_) => false,
            #[cfg(windows)]
            WriterInnerLock::Windows { .. } => true,
        }
    }
}

/// Writes colored buffers to stdout or stderr.
///
/// Writable buffers can be obtained by calling `buffer` on a `BufferWriter`.
///
/// This writer works with terminals that support ANSI escape sequences or
/// with a Windows console.
///
/// It is intended for a `BufferWriter` to be put in an `Arc` and written to
/// from multiple threads simultaneously.
pub struct BufferWriter {
    stream: LossyStandardStream<IoStandardStream>,
    printed: AtomicBool,
    separator: Option<Vec<u8>>,
    color_choice: ColorChoice,
    #[cfg(windows)]
    console: Option<Mutex<wincon::Console>>,
}

impl BufferWriter {
    /// Create a new `BufferWriter` that writes to a standard stream with the
    /// given color preferences.
    ///
    /// The specific color/style settings can be configured when writing to
    /// the buffers themselves.
    #[cfg(not(windows))]
    fn create(sty: StandardStreamType, choice: ColorChoice) -> BufferWriter {
        BufferWriter {
            stream: LossyStandardStream::new(IoStandardStream::new(sty)),
            printed: AtomicBool::new(false),
            separator: None,
            color_choice: choice,
        }
    }

    /// Create a new `BufferWriter` that writes to a standard stream with the
    /// given color preferences.
    ///
    /// If coloring is desired and a Windows console could not be found, then
    /// ANSI escape sequences are used instead.
    ///
    /// The specific color/style settings can be configured when writing to
    /// the buffers themselves.
    #[cfg(windows)]
    fn create(sty: StandardStreamType, choice: ColorChoice) -> BufferWriter {
        let mut con = match sty {
            StandardStreamType::Stdout => wincon::Console::stdout(),
            StandardStreamType::Stderr => wincon::Console::stderr(),
            StandardStreamType::StdoutBuffered => wincon::Console::stdout(),
            StandardStreamType::StderrBuffered => wincon::Console::stderr(),
        }
        .ok();
        let is_console_virtual = con
            .as_mut()
            .map(|con| con.set_virtual_terminal_processing(true).is_ok())
            .unwrap_or(false);
        // If we can enable ANSI on Windows, then we don't need the console
        // anymore.
        if is_console_virtual {
            con = None;
        }
        let stream = LossyStandardStream::new(IoStandardStream::new(sty));
        BufferWriter {
            stream: stream,
            printed: AtomicBool::new(false),
            separator: None,
            color_choice: choice,
            console: con.map(Mutex::new),
        }
    }

    /// Create a new `BufferWriter` that writes to stdout with the given
    /// color preferences.
    ///
    /// On Windows, if coloring is desired and a Windows console could not be
    /// found, then ANSI escape sequences are used instead.
    ///
    /// The specific color/style settings can be configured when writing to
    /// the buffers themselves.
    pub fn stdout(choice: ColorChoice) -> BufferWriter {
        BufferWriter::create(StandardStreamType::Stdout, choice)
    }

    /// Create a new `BufferWriter` that writes to stderr with the given
    /// color preferences.
    ///
    /// On Windows, if coloring is desired and a Windows console could not be
    /// found, then ANSI escape sequences are used instead.
    ///
    /// The specific color/style settings can be configured when writing to
    /// the buffers themselves.
    pub fn stderr(choice: ColorChoice) -> BufferWriter {
        BufferWriter::create(StandardStreamType::Stderr, choice)
    }

    /// If set, the separator given is printed between buffers. By default, no
    /// separator is printed.
    ///
    /// The default value is `None`.
    pub fn separator(&mut self, sep: Option<Vec<u8>>) {
        self.separator = sep;
    }

    /// Creates a new `Buffer` with the current color preferences.
    ///
    /// A `Buffer` satisfies both `io::Write` and `WriteColor`. A `Buffer` can
    /// be printed using the `print` method.
    #[cfg(not(windows))]
    pub fn buffer(&self) -> Buffer {
        Buffer::new(self.color_choice)
    }

    /// Creates a new `Buffer` with the current color preferences.
    ///
    /// A `Buffer` satisfies both `io::Write` and `WriteColor`. A `Buffer` can
    /// be printed using the `print` method.
    #[cfg(windows)]
    pub fn buffer(&self) -> Buffer {
        Buffer::new(self.color_choice, self.console.is_some())
    }

    /// Prints the contents of the given buffer.
    ///
    /// It is safe to call this from multiple threads simultaneously. In
    /// particular, all buffers are written atomically. No interleaving will
    /// occur.
    pub fn print(&self, buf: &Buffer) -> io::Result<()> {
        if buf.is_empty() {
            return Ok(());
        }
        let mut stream = self.stream.wrap(self.stream.get_ref().lock());
        if let Some(ref sep) = self.separator {
            if self.printed.load(Ordering::SeqCst) {
                stream.write_all(sep)?;
                stream.write_all(b"\n")?;
            }
        }
        match buf.0 {
            BufferInner::NoColor(ref b) => stream.write_all(&b.0)?,
            BufferInner::Ansi(ref b) => stream.write_all(&b.0)?,
            #[cfg(windows)]
            BufferInner::Windows(ref b) => {
                // We guarantee by construction that we have a console here.
                // Namely, a BufferWriter is the only way to produce a Buffer.
                let console_mutex = self
                    .console
                    .as_ref()
                    .expect("got Windows buffer but have no Console");
                let mut console = console_mutex.lock().unwrap();
                b.print(&mut *console, &mut stream)?;
            }
        }
        self.printed.store(true, Ordering::SeqCst);
        Ok(())
    }
}

/// Write colored text to memory.
///
/// `Buffer` is a platform independent abstraction for printing colored text to
/// an in memory buffer. When the buffer is printed using a `BufferWriter`, the
/// color information will be applied to the output device (a tty on Unix and a
/// console on Windows).
///
/// A `Buffer` is typically created by calling the `BufferWriter.buffer`
/// method, which will take color preferences and the environment into
/// account. However, buffers can also be manually created using `no_color`,
/// `ansi` or `console` (on Windows).
pub struct Buffer(BufferInner);

/// BufferInner is an enumeration of different buffer types.
enum BufferInner {
    /// No coloring information should be applied. This ignores all coloring
    /// directives.
    NoColor(NoColor<Vec<u8>>),
    /// Apply coloring using ANSI escape sequences embedded into the buffer.
    Ansi(Ansi<Vec<u8>>),
    /// Apply coloring using the Windows console APIs. This buffer saves
    /// color information in memory and only interacts with the console when
    /// the buffer is printed.
    #[cfg(windows)]
    Windows(WindowsBuffer),
}

impl Buffer {
    /// Create a new buffer with the given color settings.
    #[cfg(not(windows))]
    fn new(choice: ColorChoice) -> Buffer {
        if choice.should_attempt_color() {
            Buffer::ansi()
        } else {
            Buffer::no_color()
        }
    }

    /// Create a new buffer with the given color settings.
    ///
    /// On Windows, one can elect to create a buffer capable of being written
    /// to a console. Only enable it if a console is available.
    ///
    /// If coloring is desired and `console` is false, then ANSI escape
    /// sequences are used instead.
    #[cfg(windows)]
    fn new(choice: ColorChoice, console: bool) -> Buffer {
        if choice.should_attempt_color() {
            if !console || choice.should_ansi() {
                Buffer::ansi()
            } else {
                Buffer::console()
            }
        } else {
            Buffer::no_color()
        }
    }

    /// Create a buffer that drops all color information.
    pub fn no_color() -> Buffer {
        Buffer(BufferInner::NoColor(NoColor(vec![])))
    }

    /// Create a buffer that uses ANSI escape sequences.
    pub fn ansi() -> Buffer {
        Buffer(BufferInner::Ansi(Ansi(vec![])))
    }

    /// Create a buffer that can be written to a Windows console.
    #[cfg(windows)]
    pub fn console() -> Buffer {
        Buffer(BufferInner::Windows(WindowsBuffer::new()))
    }

    /// Returns true if and only if this buffer is empty.
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// Returns the length of this buffer in bytes.
    pub fn len(&self) -> usize {
        match self.0 {
            BufferInner::NoColor(ref b) => b.0.len(),
            BufferInner::Ansi(ref b) => b.0.len(),
            #[cfg(windows)]
            BufferInner::Windows(ref b) => b.buf.len(),
        }
    }

    /// Clears this buffer.
    pub fn clear(&mut self) {
        match self.0 {
            BufferInner::NoColor(ref mut b) => b.0.clear(),
            BufferInner::Ansi(ref mut b) => b.0.clear(),
            #[cfg(windows)]
            BufferInner::Windows(ref mut b) => b.clear(),
        }
    }

    /// Consume this buffer and return the underlying raw data.
    ///
    /// On Windows, this unrecoverably drops all color information associated
    /// with the buffer.
    pub fn into_inner(self) -> Vec<u8> {
        match self.0 {
            BufferInner::NoColor(b) => b.0,
            BufferInner::Ansi(b) => b.0,
            #[cfg(windows)]
            BufferInner::Windows(b) => b.buf,
        }
    }

    /// Return the underlying data of the buffer.
    pub fn as_slice(&self) -> &[u8] {
        match self.0 {
            BufferInner::NoColor(ref b) => &b.0,
            BufferInner::Ansi(ref b) => &b.0,
            #[cfg(windows)]
            BufferInner::Windows(ref b) => &b.buf,
        }
    }

    /// Return the underlying data of the buffer as a mutable slice.
    pub fn as_mut_slice(&mut self) -> &mut [u8] {
        match self.0 {
            BufferInner::NoColor(ref mut b) => &mut b.0,
            BufferInner::Ansi(ref mut b) => &mut b.0,
            #[cfg(windows)]
            BufferInner::Windows(ref mut b) => &mut b.buf,
        }
    }
}

impl io::Write for Buffer {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        match self.0 {
            BufferInner::NoColor(ref mut w) => w.write(buf),
            BufferInner::Ansi(ref mut w) => w.write(buf),
            #[cfg(windows)]
            BufferInner::Windows(ref mut w) => w.write(buf),
        }
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        match self.0 {
            BufferInner::NoColor(ref mut w) => w.flush(),
            BufferInner::Ansi(ref mut w) => w.flush(),
            #[cfg(windows)]
            BufferInner::Windows(ref mut w) => w.flush(),
        }
    }
}

impl WriteColor for Buffer {
    #[inline]
    fn supports_color(&self) -> bool {
        match self.0 {
            BufferInner::NoColor(_) => false,
            BufferInner::Ansi(_) => true,
            #[cfg(windows)]
            BufferInner::Windows(_) => true,
        }
    }

    #[inline]
    fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
        match self.0 {
            BufferInner::NoColor(ref mut w) => w.set_color(spec),
            BufferInner::Ansi(ref mut w) => w.set_color(spec),
            #[cfg(windows)]
            BufferInner::Windows(ref mut w) => w.set_color(spec),
        }
    }

    #[inline]
    fn reset(&mut self) -> io::Result<()> {
        match self.0 {
            BufferInner::NoColor(ref mut w) => w.reset(),
            BufferInner::Ansi(ref mut w) => w.reset(),
            #[cfg(windows)]
            BufferInner::Windows(ref mut w) => w.reset(),
        }
    }

    #[inline]
    fn is_synchronous(&self) -> bool {
        false
    }
}

/// Satisfies `WriteColor` but ignores all color options.
pub struct NoColor<W>(W);

impl<W: Write> NoColor<W> {
    /// Create a new writer that satisfies `WriteColor` but drops all color
    /// information.
    pub fn new(wtr: W) -> NoColor<W> {
        NoColor(wtr)
    }

    /// Consume this `NoColor` value and return the inner writer.
    pub fn into_inner(self) -> W {
        self.0
    }

    /// Return a reference to the inner writer.
    pub fn get_ref(&self) -> &W {
        &self.0
    }

    /// Return a mutable reference to the inner writer.
    pub fn get_mut(&mut self) -> &mut W {
        &mut self.0
    }
}

impl<W: io::Write> io::Write for NoColor<W> {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        self.0.flush()
    }
}

impl<W: io::Write> WriteColor for NoColor<W> {
    #[inline]
    fn supports_color(&self) -> bool {
        false
    }

    #[inline]
    fn set_color(&mut self, _: &ColorSpec) -> io::Result<()> {
        Ok(())
    }

    #[inline]
    fn reset(&mut self) -> io::Result<()> {
        Ok(())
    }

    #[inline]
    fn is_synchronous(&self) -> bool {
        false
    }
}

/// Satisfies `WriteColor` using standard ANSI escape sequences.
pub struct Ansi<W>(W);

impl<W: Write> Ansi<W> {
    /// Create a new writer that satisfies `WriteColor` using standard ANSI
    /// escape sequences.
    pub fn new(wtr: W) -> Ansi<W> {
        Ansi(wtr)
    }

    /// Consume this `Ansi` value and return the inner writer.
    pub fn into_inner(self) -> W {
        self.0
    }

    /// Return a reference to the inner writer.
    pub fn get_ref(&self) -> &W {
        &self.0
    }

    /// Return a mutable reference to the inner writer.
    pub fn get_mut(&mut self) -> &mut W {
        &mut self.0
    }
}

impl<W: io::Write> io::Write for Ansi<W> {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.0.write(buf)
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        self.0.flush()
    }
}

impl<W: io::Write> WriteColor for Ansi<W> {
    #[inline]
    fn supports_color(&self) -> bool {
        true
    }

    #[inline]
    fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
        if spec.reset {
            self.reset()?;
        }
        if spec.bold {
            self.write_str("\x1B[1m")?;
        }
        if spec.dimmed {
            self.write_str("\x1B[2m")?;
        }
        if spec.italic {
            self.write_str("\x1B[3m")?;
        }
        if spec.underline {
            self.write_str("\x1B[4m")?;
        }
        if let Some(ref c) = spec.fg_color {
            self.write_color(true, c, spec.intense)?;
        }
        if let Some(ref c) = spec.bg_color {
            self.write_color(false, c, spec.intense)?;
        }
        Ok(())
    }

    #[inline]
    fn reset(&mut self) -> io::Result<()> {
        self.write_str("\x1B[0m")
    }

    #[inline]
    fn is_synchronous(&self) -> bool {
        false
    }
}

impl<W: io::Write> Ansi<W> {
    fn write_str(&mut self, s: &str) -> io::Result<()> {
        self.write_all(s.as_bytes())
    }

    fn write_color(
        &mut self,
        fg: bool,
        c: &Color,
        intense: bool,
    ) -> io::Result<()> {
        macro_rules! write_intense {
            ($clr:expr) => {
                if fg {
                    self.write_str(concat!("\x1B[38;5;", $clr, "m"))
                } else {
                    self.write_str(concat!("\x1B[48;5;", $clr, "m"))
                }
            };
        }
        macro_rules! write_normal {
            ($clr:expr) => {
                if fg {
                    self.write_str(concat!("\x1B[3", $clr, "m"))
                } else {
                    self.write_str(concat!("\x1B[4", $clr, "m"))
                }
            };
        }
        macro_rules! write_var_ansi_code {
            ($pre:expr, $($code:expr),+) => {{
                // The loop generates at worst a literal of the form
                // '255,255,255m' which is 12-bytes.
                // The largest `pre` expression we currently use is 7 bytes.
                // This gives us the maximum of 19-bytes for our work buffer.
                let pre_len = $pre.len();
                assert!(pre_len <= 7);
                let mut fmt = [0u8; 19];
                fmt[..pre_len].copy_from_slice($pre);
                let mut i = pre_len - 1;
                $(
                    let c1: u8 = ($code / 100) % 10;
                    let c2: u8 = ($code / 10) % 10;
                    let c3: u8 = $code % 10;
                    let mut printed = false;

                    if c1 != 0 {
                        printed = true;
                        i += 1;
                        fmt[i] = b'0' + c1;
                    }
                    if c2 != 0 || printed {
                        i += 1;
                        fmt[i] = b'0' + c2;
                    }
                    // If we received a zero value we must still print a value.
                    i += 1;
                    fmt[i] = b'0' + c3;
                    i += 1;
                    fmt[i] = b';';
                )+

                fmt[i] = b'm';
                self.write_all(&fmt[0..i+1])
            }}
        }
        macro_rules! write_custom {
            ($ansi256:expr) => {
                if fg {
                    write_var_ansi_code!(b"\x1B[38;5;", $ansi256)
                } else {
                    write_var_ansi_code!(b"\x1B[48;5;", $ansi256)
                }
            };

            ($r:expr, $g:expr, $b:expr) => {{
                if fg {
                    write_var_ansi_code!(b"\x1B[38;2;", $r, $g, $b)
                } else {
                    write_var_ansi_code!(b"\x1B[48;2;", $r, $g, $b)
                }
            }};
        }
        if intense {
            match *c {
                Color::Black => write_intense!("8"),
                Color::Blue => write_intense!("12"),
                Color::Green => write_intense!("10"),
                Color::Red => write_intense!("9"),
                Color::Cyan => write_intense!("14"),
                Color::Magenta => write_intense!("13"),
                Color::Yellow => write_intense!("11"),
                Color::White => write_intense!("15"),
                Color::Ansi256(c) => write_custom!(c),
                Color::Rgb(r, g, b) => write_custom!(r, g, b),
                Color::__Nonexhaustive => unreachable!(),
            }
        } else {
            match *c {
                Color::Black => write_normal!("0"),
                Color::Blue => write_normal!("4"),
                Color::Green => write_normal!("2"),
                Color::Red => write_normal!("1"),
                Color::Cyan => write_normal!("6"),
                Color::Magenta => write_normal!("5"),
                Color::Yellow => write_normal!("3"),
                Color::White => write_normal!("7"),
                Color::Ansi256(c) => write_custom!(c),
                Color::Rgb(r, g, b) => write_custom!(r, g, b),
                Color::__Nonexhaustive => unreachable!(),
            }
        }
    }
}

/// An in-memory buffer that provides Windows console coloring.
///
/// This doesn't actually communicate with the Windows console. Instead, it
/// acts like a normal buffer but also saves the color information associated
/// with positions in the buffer. It is only when the buffer is written to the
/// console that coloring is actually applied.
///
/// This is roughly isomorphic to the ANSI based approach (i.e.,
/// `Ansi<Vec<u8>>`), except with ANSI, the color information is embedded
/// directly into the buffer.
///
/// Note that there is no way to write something generic like
/// `WindowsConsole<W: io::Write>` since coloring on Windows is tied
/// specifically to the console APIs, and therefore can't work on arbitrary
/// writers.
#[cfg(windows)]
#[derive(Clone, Debug)]
struct WindowsBuffer {
    /// The actual content that should be printed.
    buf: Vec<u8>,
    /// A sequence of position oriented color specifications. Namely, each
    /// element is a position and a color spec, where the color spec should
    /// be applied at the position inside of `buf`.
    ///
    /// A missing color spec implies the underlying console should be reset.
    colors: Vec<(usize, Option<ColorSpec>)>,
}

#[cfg(windows)]
impl WindowsBuffer {
    /// Create a new empty buffer for Windows console coloring.
    fn new() -> WindowsBuffer {
        WindowsBuffer { buf: vec![], colors: vec![] }
    }

    /// Push the given color specification into this buffer.
    ///
    /// This has the effect of setting the given color information at the
    /// current position in the buffer.
    fn push(&mut self, spec: Option<ColorSpec>) {
        let pos = self.buf.len();
        self.colors.push((pos, spec));
    }

    /// Print the contents to the given stream handle, and use the console
    /// for coloring.
    fn print(
        &self,
        console: &mut wincon::Console,
        stream: &mut LossyStandardStream<IoStandardStreamLock>,
    ) -> io::Result<()> {
        let mut last = 0;
        for &(pos, ref spec) in &self.colors {
            stream.write_all(&self.buf[last..pos])?;
            stream.flush()?;
            last = pos;
            match *spec {
                None => console.reset()?,
                Some(ref spec) => spec.write_console(console)?,
            }
        }
        stream.write_all(&self.buf[last..])?;
        stream.flush()
    }

    /// Clear the buffer.
    fn clear(&mut self) {
        self.buf.clear();
        self.colors.clear();
    }
}

#[cfg(windows)]
impl io::Write for WindowsBuffer {
    #[inline]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.buf.extend_from_slice(buf);
        Ok(buf.len())
    }

    #[inline]
    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

#[cfg(windows)]
impl WriteColor for WindowsBuffer {
    #[inline]
    fn supports_color(&self) -> bool {
        true
    }

    #[inline]
    fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
        self.push(Some(spec.clone()));
        Ok(())
    }

    #[inline]
    fn reset(&mut self) -> io::Result<()> {
        self.push(None);
        Ok(())
    }

    #[inline]
    fn is_synchronous(&self) -> bool {
        false
    }
}

/// A color specification.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ColorSpec {
    fg_color: Option<Color>,
    bg_color: Option<Color>,
    bold: bool,
    intense: bool,
    underline: bool,
    dimmed: bool,
    italic: bool,
    reset: bool,
}

impl Default for ColorSpec {
    fn default() -> ColorSpec {
        ColorSpec {
            fg_color: None,
            bg_color: None,
            bold: false,
            intense: false,
            underline: false,
            dimmed: false,
            italic: false,
            reset: true,
        }
    }
}

impl ColorSpec {
    /// Create a new color specification that has no colors or styles.
    pub fn new() -> ColorSpec {
        ColorSpec::default()
    }

    /// Get the foreground color.
    pub fn fg(&self) -> Option<&Color> {
        self.fg_color.as_ref()
    }

    /// Set the foreground color.
    pub fn set_fg(&mut self, color: Option<Color>) -> &mut ColorSpec {
        self.fg_color = color;
        self
    }

    /// Get the background color.
    pub fn bg(&self) -> Option<&Color> {
        self.bg_color.as_ref()
    }

    /// Set the background color.
    pub fn set_bg(&mut self, color: Option<Color>) -> &mut ColorSpec {
        self.bg_color = color;
        self
    }

    /// Get whether this is bold or not.
    ///
    /// Note that the bold setting has no effect in a Windows console.
    pub fn bold(&self) -> bool {
        self.bold
    }

    /// Set whether the text is bolded or not.
    ///
    /// Note that the bold setting has no effect in a Windows console.
    pub fn set_bold(&mut self, yes: bool) -> &mut ColorSpec {
        self.bold = yes;
        self
    }

    /// Get whether this is dimmed or not.
    ///
    /// Note that the dimmed setting has no effect in a Windows console.
    pub fn dimmed(&self) -> bool {
        self.dimmed
    }

    /// Set whether the text is dimmed or not.
    ///
    /// Note that the dimmed setting has no effect in a Windows console.
    pub fn set_dimmed(&mut self, yes: bool) -> &mut ColorSpec {
        self.dimmed = yes;
        self
    }

    /// Get whether this is italic or not.
    ///
    /// Note that the italic setting has no effect in a Windows console.
    pub fn italic(&self) -> bool {
        self.italic
    }

    /// Set whether the text is italicized or not.
    ///
    /// Note that the italic setting has no effect in a Windows console.
    pub fn set_italic(&mut self, yes: bool) -> &mut ColorSpec {
        self.italic = yes;
        self
    }

    /// Get whether this is underline or not.
    ///
    /// Note that the underline setting has no effect in a Windows console.
    pub fn underline(&self) -> bool {
        self.underline
    }

    /// Set whether the text is underlined or not.
    ///
    /// Note that the underline setting has no effect in a Windows console.
    pub fn set_underline(&mut self, yes: bool) -> &mut ColorSpec {
        self.underline = yes;
        self
    }

    /// Get whether reset is enabled or not.
    ///
    /// reset is enabled by default. When disabled and using ANSI escape
    /// sequences, a "reset" code will be emitted every time a `ColorSpec`'s
    /// settings are applied.
    ///
    /// Note that the reset setting has no effect in a Windows console.
    pub fn reset(&self) -> bool {
        self.reset
    }

    /// Set whether to reset the terminal whenever color settings are applied.
    ///
    /// reset is enabled by default. When disabled and using ANSI escape
    /// sequences, a "reset" code will be emitted every time a `ColorSpec`'s
    /// settings are applied.
    ///
    /// Typically this is useful if callers have a requirement to more
    /// scrupulously manage the exact sequence of escape codes that are emitted
    /// when using ANSI for colors.
    ///
    /// Note that the reset setting has no effect in a Windows console.
    pub fn set_reset(&mut self, yes: bool) -> &mut ColorSpec {
        self.reset = yes;
        self
    }

    /// Get whether this is intense or not.
    ///
    /// On Unix-like systems, this will output the ANSI escape sequence
    /// that will print a high-intensity version of the color
    /// specified.
    ///
    /// On Windows systems, this will output the ANSI escape sequence
    /// that will print a brighter version of the color specified.
    pub fn intense(&self) -> bool {
        self.intense
    }

    /// Set whether the text is intense or not.
    ///
    /// On Unix-like systems, this will output the ANSI escape sequence
    /// that will print a high-intensity version of the color
    /// specified.
    ///
    /// On Windows systems, this will output the ANSI escape sequence
    /// that will print a brighter version of the color specified.
    pub fn set_intense(&mut self, yes: bool) -> &mut ColorSpec {
        self.intense = yes;
        self
    }

    /// Returns true if this color specification has no colors or styles.
    pub fn is_none(&self) -> bool {
        self.fg_color.is_none()
            && self.bg_color.is_none()
            && !self.bold
            && !self.underline
            && !self.dimmed
            && !self.italic
            && !self.intense
    }

    /// Clears this color specification so that it has no color/style settings.
    pub fn clear(&mut self) {
        self.fg_color = None;
        self.bg_color = None;
        self.bold = false;
        self.underline = false;
        self.intense = false;
        self.dimmed = false;
        self.italic = false;
    }

    /// Writes this color spec to the given Windows console.
    #[cfg(windows)]
    fn write_console(&self, console: &mut wincon::Console) -> io::Result<()> {
        let fg_color = self.fg_color.and_then(|c| c.to_windows(self.intense));
        if let Some((intense, color)) = fg_color {
            console.fg(intense, color)?;
        }
        let bg_color = self.bg_color.and_then(|c| c.to_windows(self.intense));
        if let Some((intense, color)) = bg_color {
            console.bg(intense, color)?;
        }
        Ok(())
    }
}

/// The set of available colors for the terminal foreground/background.
///
/// The `Ansi256` and `Rgb` colors will only output the correct codes when
/// paired with the `Ansi` `WriteColor` implementation.
///
/// The `Ansi256` and `Rgb` color types are not supported when writing colors
/// on Windows using the console. If they are used on Windows, then they are
/// silently ignored and no colors will be emitted.
///
/// This set may expand over time.
///
/// This type has a `FromStr` impl that can parse colors from their human
/// readable form. The format is as follows:
///
/// 1. Any of the explicitly listed colors in English. They are matched
///    case insensitively.
/// 2. A single 8-bit integer, in either decimal or hexadecimal format.
/// 3. A triple of 8-bit integers separated by a comma, where each integer is
///    in decimal or hexadecimal format.
///
/// Hexadecimal numbers are written with a `0x` prefix.
#[allow(missing_docs)]
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum Color {
    Black,
    Blue,
    Green,
    Red,
    Cyan,
    Magenta,
    Yellow,
    White,
    Ansi256(u8),
    Rgb(u8, u8, u8),
    #[doc(hidden)]
    __Nonexhaustive,
}

impl Color {
    /// Translate this color to a wincon::Color.
    #[cfg(windows)]
    fn to_windows(
        self,
        intense: bool,
    ) -> Option<(wincon::Intense, wincon::Color)> {
        use wincon::Intense::{No, Yes};

        let color = match self {
            Color::Black => wincon::Color::Black,
            Color::Blue => wincon::Color::Blue,
            Color::Green => wincon::Color::Green,
            Color::Red => wincon::Color::Red,
            Color::Cyan => wincon::Color::Cyan,
            Color::Magenta => wincon::Color::Magenta,
            Color::Yellow => wincon::Color::Yellow,
            Color::White => wincon::Color::White,
            Color::Ansi256(0) => return Some((No, wincon::Color::Black)),
            Color::Ansi256(1) => return Some((No, wincon::Color::Red)),
            Color::Ansi256(2) => return Some((No, wincon::Color::Green)),
            Color::Ansi256(3) => return Some((No, wincon::Color::Yellow)),
            Color::Ansi256(4) => return Some((No, wincon::Color::Blue)),
            Color::Ansi256(5) => return Some((No, wincon::Color::Magenta)),
            Color::Ansi256(6) => return Some((No, wincon::Color::Cyan)),
            Color::Ansi256(7) => return Some((No, wincon::Color::White)),
            Color::Ansi256(8) => return Some((Yes, wincon::Color::Black)),
            Color::Ansi256(9) => return Some((Yes, wincon::Color::Red)),
            Color::Ansi256(10) => return Some((Yes, wincon::Color::Green)),
            Color::Ansi256(11) => return Some((Yes, wincon::Color::Yellow)),
            Color::Ansi256(12) => return Some((Yes, wincon::Color::Blue)),
            Color::Ansi256(13) => return Some((Yes, wincon::Color::Magenta)),
            Color::Ansi256(14) => return Some((Yes, wincon::Color::Cyan)),
            Color::Ansi256(15) => return Some((Yes, wincon::Color::White)),
            Color::Ansi256(_) => return None,
            Color::Rgb(_, _, _) => return None,
            Color::__Nonexhaustive => unreachable!(),
        };
        let intense = if intense { Yes } else { No };
        Some((intense, color))
    }

    /// Parses a numeric color string, either ANSI or RGB.
    fn from_str_numeric(s: &str) -> Result<Color, ParseColorError> {
        // The "ansi256" format is a single number (decimal or hex)
        // corresponding to one of 256 colors.
        //
        // The "rgb" format is a triple of numbers (decimal or hex) delimited
        // by a comma corresponding to one of 256^3 colors.

        fn parse_number(s: &str) -> Option<u8> {
            use std::u8;

            if s.starts_with("0x") {
                u8::from_str_radix(&s[2..], 16).ok()
            } else {
                u8::from_str_radix(s, 10).ok()
            }
        }

        let codes: Vec<&str> = s.split(',').collect();
        if codes.len() == 1 {
            if let Some(n) = parse_number(&codes[0]) {
                Ok(Color::Ansi256(n))
            } else {
                if s.chars().all(|c| c.is_digit(16)) {
                    Err(ParseColorError {
                        kind: ParseColorErrorKind::InvalidAnsi256,
                        given: s.to_string(),
                    })
                } else {
                    Err(ParseColorError {
                        kind: ParseColorErrorKind::InvalidName,
                        given: s.to_string(),
                    })
                }
            }
        } else if codes.len() == 3 {
            let mut v = vec![];
            for code in codes {
                let n = parse_number(code).ok_or_else(|| ParseColorError {
                    kind: ParseColorErrorKind::InvalidRgb,
                    given: s.to_string(),
                })?;
                v.push(n);
            }
            Ok(Color::Rgb(v[0], v[1], v[2]))
        } else {
            Err(if s.contains(",") {
                ParseColorError {
                    kind: ParseColorErrorKind::InvalidRgb,
                    given: s.to_string(),
                }
            } else {
                ParseColorError {
                    kind: ParseColorErrorKind::InvalidName,
                    given: s.to_string(),
                }
            })
        }
    }
}

/// An error from parsing an invalid color specification.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ParseColorError {
    kind: ParseColorErrorKind,
    given: String,
}

#[derive(Clone, Debug, Eq, PartialEq)]
enum ParseColorErrorKind {
    InvalidName,
    InvalidAnsi256,
    InvalidRgb,
}

impl ParseColorError {
    /// Return the string that couldn't be parsed as a valid color.
    pub fn invalid(&self) -> &str {
        &self.given
    }
}

impl error::Error for ParseColorError {
    fn description(&self) -> &str {
        use self::ParseColorErrorKind::*;
        match self.kind {
            InvalidName => "unrecognized color name",
            InvalidAnsi256 => "invalid ansi256 color number",
            InvalidRgb => "invalid RGB color triple",
        }
    }
}

impl fmt::Display for ParseColorError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        use self::ParseColorErrorKind::*;
        match self.kind {
            InvalidName => write!(
                f,
                "unrecognized color name '{}'. Choose from: \
                 black, blue, green, red, cyan, magenta, yellow, \
                 white",
                self.given
            ),
            InvalidAnsi256 => write!(
                f,
                "unrecognized ansi256 color number, \
                 should be '[0-255]' (or a hex number), but is '{}'",
                self.given
            ),
            InvalidRgb => write!(
                f,
                "unrecognized RGB color triple, \
                 should be '[0-255],[0-255],[0-255]' (or a hex \
                 triple), but is '{}'",
                self.given
            ),
        }
    }
}

impl FromStr for Color {
    type Err = ParseColorError;

    fn from_str(s: &str) -> Result<Color, ParseColorError> {
        match &*s.to_lowercase() {
            "black" => Ok(Color::Black),
            "blue" => Ok(Color::Blue),
            "green" => Ok(Color::Green),
            "red" => Ok(Color::Red),
            "cyan" => Ok(Color::Cyan),
            "magenta" => Ok(Color::Magenta),
            "yellow" => Ok(Color::Yellow),
            "white" => Ok(Color::White),
            _ => Color::from_str_numeric(s),
        }
    }
}

struct LossyStandardStream<W> {
    wtr: W,
    #[cfg(windows)]
    is_console: bool,
}

impl<W: io::Write> LossyStandardStream<W> {
    #[cfg(not(windows))]
    fn new(wtr: W) -> LossyStandardStream<W> {
        LossyStandardStream { wtr: wtr }
    }

    #[cfg(windows)]
    fn new(wtr: W) -> LossyStandardStream<W> {
        let is_console = wincon::Console::stdout().is_ok()
            || wincon::Console::stderr().is_ok();
        LossyStandardStream { wtr: wtr, is_console: is_console }
    }

    #[cfg(not(windows))]
    fn wrap<Q: io::Write>(&self, wtr: Q) -> LossyStandardStream<Q> {
        LossyStandardStream::new(wtr)
    }

    #[cfg(windows)]
    fn wrap<Q: io::Write>(&self, wtr: Q) -> LossyStandardStream<Q> {
        LossyStandardStream { wtr: wtr, is_console: self.is_console }
    }

    fn get_ref(&self) -> &W {
        &self.wtr
    }
}

impl<W: WriteColor> WriteColor for LossyStandardStream<W> {
    fn supports_color(&self) -> bool {
        self.wtr.supports_color()
    }
    fn set_color(&mut self, spec: &ColorSpec) -> io::Result<()> {
        self.wtr.set_color(spec)
    }
    fn reset(&mut self) -> io::Result<()> {
        self.wtr.reset()
    }
    fn is_synchronous(&self) -> bool {
        self.wtr.is_synchronous()
    }
}

impl<W: io::Write> io::Write for LossyStandardStream<W> {
    #[cfg(not(windows))]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        self.wtr.write(buf)
    }

    #[cfg(windows)]
    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
        if self.is_console {
            write_lossy_utf8(&mut self.wtr, buf)
        } else {
            self.wtr.write(buf)
        }
    }

    fn flush(&mut self) -> io::Result<()> {
        self.wtr.flush()
    }
}

#[cfg(windows)]
fn write_lossy_utf8<W: io::Write>(mut w: W, buf: &[u8]) -> io::Result<usize> {
    match ::std::str::from_utf8(buf) {
        Ok(s) => w.write(s.as_bytes()),
        Err(ref e) if e.valid_up_to() == 0 => {
            w.write(b"\xEF\xBF\xBD")?;
            Ok(1)
        }
        Err(e) => w.write(&buf[..e.valid_up_to()]),
    }
}

#[cfg(test)]
mod tests {
    use super::{
        Ansi, Color, ColorSpec, ParseColorError, ParseColorErrorKind,
        StandardStream, WriteColor,
    };

    fn assert_is_send<T: Send>() {}

    #[test]
    fn standard_stream_is_send() {
        assert_is_send::<StandardStream>();
    }

    #[test]
    fn test_simple_parse_ok() {
        let color = "green".parse::<Color>();
        assert_eq!(color, Ok(Color::Green));
    }

    #[test]
    fn test_256_parse_ok() {
        let color = "7".parse::<Color>();
        assert_eq!(color, Ok(Color::Ansi256(7)));

        let color = "32".parse::<Color>();
        assert_eq!(color, Ok(Color::Ansi256(32)));

        let color = "0xFF".parse::<Color>();
        assert_eq!(color, Ok(Color::Ansi256(0xFF)));
    }

    #[test]
    fn test_256_parse_err_out_of_range() {
        let color = "256".parse::<Color>();
        assert_eq!(
            color,
            Err(ParseColorError {
                kind: ParseColorErrorKind::InvalidAnsi256,
                given: "256".to_string(),
            })
        );
    }

    #[test]
    fn test_rgb_parse_ok() {
        let color = "0,0,0".parse::<Color>();
        assert_eq!(color, Ok(Color::Rgb(0, 0, 0)));

        let color = "0,128,255".parse::<Color>();
        assert_eq!(color, Ok(Color::Rgb(0, 128, 255)));

        let color = "0x0,0x0,0x0".parse::<Color>();
        assert_eq!(color, Ok(Color::Rgb(0, 0, 0)));

        let color = "0x33,0x66,0xFF".parse::<Color>();
        assert_eq!(color, Ok(Color::Rgb(0x33, 0x66, 0xFF)));
    }

    #[test]
    fn test_rgb_parse_err_out_of_range() {
        let color = "0,0,256".parse::<Color>();
        assert_eq!(
            color,
            Err(ParseColorError {
                kind: ParseColorErrorKind::InvalidRgb,
                given: "0,0,256".to_string(),
            })
        );
    }

    #[test]
    fn test_rgb_parse_err_bad_format() {
        let color = "0,0".parse::<Color>();
        assert_eq!(
            color,
            Err(ParseColorError {
                kind: ParseColorErrorKind::InvalidRgb,
                given: "0,0".to_string(),
            })
        );

        let color = "not_a_color".parse::<Color>();
        assert_eq!(
            color,
            Err(ParseColorError {
                kind: ParseColorErrorKind::InvalidName,
                given: "not_a_color".to_string(),
            })
        );
    }

    #[test]
    fn test_var_ansi_write_rgb() {
        let mut buf = Ansi::new(vec![]);
        let _ = buf.write_color(true, &Color::Rgb(254, 253, 255), false);
        assert_eq!(buf.0, b"\x1B[38;2;254;253;255m");
    }

    #[test]
    fn test_reset() {
        let spec = ColorSpec::new();
        let mut buf = Ansi::new(vec![]);
        buf.set_color(&spec).unwrap();
        assert_eq!(buf.0, b"\x1B[0m");
    }

    #[test]
    fn test_no_reset() {
        let mut spec = ColorSpec::new();
        spec.set_reset(false);

        let mut buf = Ansi::new(vec![]);
        buf.set_color(&spec).unwrap();
        assert_eq!(buf.0, b"");
    }

    #[test]
    fn test_var_ansi_write_256() {
        let mut buf = Ansi::new(vec![]);
        let _ = buf.write_color(false, &Color::Ansi256(7), false);
        assert_eq!(buf.0, b"\x1B[48;5;7m");

        let mut buf = Ansi::new(vec![]);
        let _ = buf.write_color(false, &Color::Ansi256(208), false);
        assert_eq!(buf.0, b"\x1B[48;5;208m");
    }

    fn all_attributes() -> Vec<ColorSpec> {
        let mut result = vec![];
        for fg in vec![None, Some(Color::Red)] {
            for bg in vec![None, Some(Color::Red)] {
                for bold in vec![false, true] {
                    for underline in vec![false, true] {
                        for intense in vec![false, true] {
                            for italic in vec![false, true] {
                                for dimmed in vec![false, true] {
                                    let mut color = ColorSpec::new();
                                    color.set_fg(fg);
                                    color.set_bg(bg);
                                    color.set_bold(bold);
                                    color.set_underline(underline);
                                    color.set_intense(intense);
                                    color.set_dimmed(dimmed);
                                    color.set_italic(italic);
                                    result.push(color);
                                }
                            }
                        }
                    }
                }
            }
        }
        result
    }

    #[test]
    fn test_is_none() {
        for (i, color) in all_attributes().iter().enumerate() {
            assert_eq!(
                i == 0,
                color.is_none(),
                "{:?} => {}",
                color,
                color.is_none()
            )
        }
    }

    #[test]
    fn test_clear() {
        for color in all_attributes() {
            let mut color1 = color.clone();
            color1.clear();
            assert!(color1.is_none(), "{:?} => {:?}", color, color1);
        }
    }
}
