use std::borrow::Cow;
#[cfg(test)]
use std::sync::atomic::{AtomicBool, Ordering};
use std::sync::{Arc, Condvar, Mutex, MutexGuard, Weak};
use std::time::{Duration, Instant};
use std::{fmt, io, thread};

#[cfg(test)]
use once_cell::sync::Lazy;

use crate::draw_target::ProgressDrawTarget;
use crate::state::{AtomicPosition, BarState, ProgressFinish, Reset, TabExpandedString};
use crate::style::ProgressStyle;
use crate::{ProgressBarIter, ProgressIterator, ProgressState};

/// A progress bar or spinner
///
/// The progress bar is an [`Arc`] around its internal state. When the progress bar is cloned it
/// just increments the refcount (so the original and its clone share the same state).
#[derive(Clone)]
pub struct ProgressBar {
    state: Arc<Mutex<BarState>>,
    pos: Arc<AtomicPosition>,
    ticker: Arc<Mutex<Option<Ticker>>>,
}

impl fmt::Debug for ProgressBar {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("ProgressBar").finish()
    }
}

impl ProgressBar {
    /// Creates a new progress bar with a given length
    ///
    /// This progress bar by default draws directly to stderr, and refreshes a maximum of 15 times
    /// a second. To change the refresh rate, set the draw target to one with a different refresh
    /// rate.
    pub fn new(len: u64) -> ProgressBar {
        ProgressBar::with_draw_target(Some(len), ProgressDrawTarget::stderr())
    }

    /// Creates a completely hidden progress bar
    ///
    /// This progress bar still responds to API changes but it does not have a length or render in
    /// any way.
    pub fn hidden() -> ProgressBar {
        ProgressBar::with_draw_target(None, ProgressDrawTarget::hidden())
    }

    /// Creates a new progress bar with a given length and draw target
    pub fn with_draw_target(len: Option<u64>, draw_target: ProgressDrawTarget) -> ProgressBar {
        let pos = Arc::new(AtomicPosition::new());
        ProgressBar {
            state: Arc::new(Mutex::new(BarState::new(len, draw_target, pos.clone()))),
            pos,
            ticker: Arc::new(Mutex::new(None)),
        }
    }

    /// Get a clone of the current progress bar style.
    pub fn style(self) -> ProgressStyle {
        self.state().style.clone()
    }

    /// A convenience builder-like function for a progress bar with a given style
    pub fn with_style(self, style: ProgressStyle) -> ProgressBar {
        self.set_style(style);
        self
    }

    /// A convenience builder-like function for a progress bar with a given tab width
    pub fn with_tab_width(self, tab_width: usize) -> ProgressBar {
        self.state().set_tab_width(tab_width);
        self
    }

    /// A convenience builder-like function for a progress bar with a given prefix
    pub fn with_prefix(self, prefix: impl Into<Cow<'static, str>>) -> ProgressBar {
        let mut state = self.state();
        state.state.prefix = TabExpandedString::new(prefix.into(), state.tab_width);
        drop(state);
        self
    }

    /// A convenience builder-like function for a progress bar with a given message
    pub fn with_message(self, message: impl Into<Cow<'static, str>>) -> ProgressBar {
        let mut state = self.state();
        state.state.message = TabExpandedString::new(message.into(), state.tab_width);
        drop(state);
        self
    }

    /// A convenience builder-like function for a progress bar with a given position
    pub fn with_position(self, pos: u64) -> ProgressBar {
        self.state().state.set_pos(pos);
        self
    }

    /// A convenience builder-like function for a progress bar with a given elapsed time
    pub fn with_elapsed(self, elapsed: Duration) -> ProgressBar {
        self.state().state.started = Instant::now() - elapsed;
        self
    }

    /// Sets the finish behavior for the progress bar
    ///
    /// This behavior is invoked when [`ProgressBar`] or
    /// [`ProgressBarIter`] completes and
    /// [`ProgressBar::is_finished()`] is false.
    /// If you don't want the progress bar to be automatically finished then
    /// call `on_finish(None)`.
    ///
    /// [`ProgressBar`]: crate::ProgressBar
    /// [`ProgressBarIter`]: crate::ProgressBarIter
    /// [`ProgressBar::is_finished()`]: crate::ProgressBar::is_finished
    pub fn with_finish(self, finish: ProgressFinish) -> ProgressBar {
        self.state().on_finish = finish;
        self
    }

    /// Creates a new spinner
    ///
    /// This spinner by default draws directly to stderr. This adds the default spinner style to it.
    pub fn new_spinner() -> ProgressBar {
        let rv = ProgressBar::with_draw_target(None, ProgressDrawTarget::stderr());
        rv.set_style(ProgressStyle::default_spinner());
        rv
    }

    /// Overrides the stored style
    ///
    /// This does not redraw the bar. Call [`ProgressBar::tick()`] to force it.
    pub fn set_style(&self, style: ProgressStyle) {
        self.state().set_style(style);
    }

    /// Sets the tab width (default: 8). All tabs will be expanded to this many spaces.
    pub fn set_tab_width(&mut self, tab_width: usize) {
        let mut state = self.state();
        state.set_tab_width(tab_width);
        state.draw(true, Instant::now()).unwrap();
    }

    /// Spawns a background thread to tick the progress bar
    ///
    /// When this is enabled a background thread will regularly tick the progress bar in the given
    /// interval. This is useful to advance progress bars that are very slow by themselves.
    ///
    /// When steady ticks are enabled, calling [`ProgressBar::tick()`] on a progress bar does not
    /// have any effect.
    pub fn enable_steady_tick(&self, interval: Duration) {
        // The way we test for ticker termination is with a single static `AtomicBool`. Since cargo
        // runs tests concurrently, we have a `TICKER_TEST` lock to make sure tests using ticker
        // don't step on each other. This check catches attempts to use tickers in tests without
        // acquiring the lock.
        #[cfg(test)]
        {
            let guard = TICKER_TEST.try_lock();
            let lock_acquired = guard.is_ok();
            // Drop the guard before panicking to avoid poisoning the lock (which would cause other
            // ticker tests to fail)
            drop(guard);
            if lock_acquired {
                panic!("you must acquire the TICKER_TEST lock in your test to use this method");
            }
        }

        if interval.is_zero() {
            return;
        }

        self.stop_and_replace_ticker(Some(interval));
    }

    /// Undoes [`ProgressBar::enable_steady_tick()`]
    pub fn disable_steady_tick(&self) {
        self.stop_and_replace_ticker(None);
    }

    fn stop_and_replace_ticker(&self, interval: Option<Duration>) {
        let mut ticker_state = self.ticker.lock().unwrap();
        if let Some(ticker) = ticker_state.take() {
            ticker.stop();
        }

        *ticker_state = interval.map(|interval| Ticker::new(interval, &self.state));
    }

    /// Manually ticks the spinner or progress bar
    ///
    /// This automatically happens on any other change to a progress bar.
    pub fn tick(&self) {
        // Only tick if a `Ticker` isn't installed
        if self.ticker.lock().unwrap().is_none() {
            self.state().tick(Instant::now())
        }
    }

    /// Advances the position of the progress bar by `delta`
    pub fn inc(&self, delta: u64) {
        self.pos.inc(delta);
        let now = Instant::now();
        if self.pos.allow(now) {
            self.state().tick(now);
        }
    }

    /// A quick convenience check if the progress bar is hidden
    pub fn is_hidden(&self) -> bool {
        self.state().draw_target.is_hidden()
    }

    /// Indicates that the progress bar finished
    pub fn is_finished(&self) -> bool {
        self.state().state.is_finished()
    }

    /// Print a log line above the progress bar
    ///
    /// If the progress bar is hidden (e.g. when standard output is not a terminal), `println()`
    /// will not do anything. If you want to write to the standard output in such cases as well, use
    /// [`suspend`] instead.
    ///
    /// If the progress bar was added to a [`MultiProgress`], the log line will be
    /// printed above all other progress bars.
    ///
    /// [`suspend`]: ProgressBar::suspend
    /// [`MultiProgress`]: crate::MultiProgress
    pub fn println<I: AsRef<str>>(&self, msg: I) {
        self.state().println(Instant::now(), msg.as_ref())
    }

    /// Update the `ProgressBar`'s inner [`ProgressState`]
    pub fn update(&self, f: impl FnOnce(&mut ProgressState)) {
        self.state().update(Instant::now(), f)
    }

    /// Sets the position of the progress bar
    pub fn set_position(&self, pos: u64) {
        self.pos.set(pos);
        let now = Instant::now();
        if self.pos.allow(now) {
            self.state().tick(now);
        }
    }

    /// Sets the length of the progress bar
    pub fn set_length(&self, len: u64) {
        self.state().set_length(Instant::now(), len)
    }

    /// Increase the length of the progress bar
    pub fn inc_length(&self, delta: u64) {
        self.state().inc_length(Instant::now(), delta)
    }

    /// Sets the current prefix of the progress bar
    ///
    /// For the prefix to be visible, the `{prefix}` placeholder must be present in the template
    /// (see [`ProgressStyle`]).
    pub fn set_prefix(&self, prefix: impl Into<Cow<'static, str>>) {
        let mut state = self.state();
        state.state.prefix = TabExpandedString::new(prefix.into(), state.tab_width);
        state.update_estimate_and_draw(Instant::now());
    }

    /// Sets the current message of the progress bar
    ///
    /// For the message to be visible, the `{msg}` placeholder must be present in the template (see
    /// [`ProgressStyle`]).
    pub fn set_message(&self, msg: impl Into<Cow<'static, str>>) {
        let mut state = self.state();
        state.state.message = TabExpandedString::new(msg.into(), state.tab_width);
        state.update_estimate_and_draw(Instant::now());
    }

    /// Creates a new weak reference to this `ProgressBar`
    pub fn downgrade(&self) -> WeakProgressBar {
        WeakProgressBar {
            state: Arc::downgrade(&self.state),
            pos: Arc::downgrade(&self.pos),
            ticker: Arc::downgrade(&self.ticker),
        }
    }

    pub(crate) fn weak_bar_state(&self) -> Weak<Mutex<BarState>> {
        Arc::downgrade(&self.state)
    }

    /// Resets the ETA calculation
    ///
    /// This can be useful if the progress bars made a large jump or was paused for a prolonged
    /// time.
    pub fn reset_eta(&self) {
        self.state().reset(Instant::now(), Reset::Eta)
    }

    /// Resets elapsed time
    pub fn reset_elapsed(&self) {
        self.state().reset(Instant::now(), Reset::Elapsed)
    }

    /// Resets all of the progress bar state
    pub fn reset(&self) {
        self.state().reset(Instant::now(), Reset::All)
    }

    /// Finishes the progress bar and leaves the current message
    pub fn finish(&self) {
        self.state()
            .finish_using_style(Instant::now(), ProgressFinish::AndLeave);
    }

    /// Finishes the progress bar and sets a message
    ///
    /// For the message to be visible, the `{msg}` placeholder must be present in the template (see
    /// [`ProgressStyle`]).
    pub fn finish_with_message(&self, msg: impl Into<Cow<'static, str>>) {
        self.state()
            .finish_using_style(Instant::now(), ProgressFinish::WithMessage(msg.into()))
    }

    /// Finishes the progress bar and completely clears it
    pub fn finish_and_clear(&self) {
        self.state()
            .finish_using_style(Instant::now(), ProgressFinish::AndClear);
    }

    /// Finishes the progress bar and leaves the current message and progress
    pub fn abandon(&self) {
        self.state()
            .finish_using_style(Instant::now(), ProgressFinish::Abandon);
    }

    /// Finishes the progress bar and sets a message, and leaves the current progress
    ///
    /// For the message to be visible, the `{msg}` placeholder must be present in the template (see
    /// [`ProgressStyle`]).
    pub fn abandon_with_message(&self, msg: impl Into<Cow<'static, str>>) {
        self.state().finish_using_style(
            Instant::now(),
            ProgressFinish::AbandonWithMessage(msg.into()),
        )
    }

    /// Finishes the progress bar using the behavior stored in the [`ProgressStyle`]
    ///
    /// See [`ProgressBar::with_finish()`].
    pub fn finish_using_style(&self) {
        let mut state = self.state();
        let finish = state.on_finish.clone();
        state.finish_using_style(Instant::now(), finish);
    }

    /// Sets a different draw target for the progress bar
    ///
    /// This can be used to draw the progress bar to stderr (this is the default):
    ///
    /// ```rust,no_run
    /// # use indicatif::{ProgressBar, ProgressDrawTarget};
    /// let pb = ProgressBar::new(100);
    /// pb.set_draw_target(ProgressDrawTarget::stderr());
    /// ```
    ///
    /// **Note:** Calling this method on a [`ProgressBar`] linked with a [`MultiProgress`] (after
    /// running [`MultiProgress::add`]) will unlink this progress bar. If you don't want this
    /// behavior, call [`MultiProgress::set_draw_target`] instead.
    ///
    /// [`MultiProgress`]: crate::MultiProgress
    /// [`MultiProgress::add`]: crate::MultiProgress::add
    /// [`MultiProgress::set_draw_target`]: crate::MultiProgress::set_draw_target
    pub fn set_draw_target(&self, target: ProgressDrawTarget) {
        let mut state = self.state();
        state.draw_target.disconnect(Instant::now());
        state.draw_target = target;
    }

    /// Hide the progress bar temporarily, execute `f`, then redraw the progress bar
    ///
    /// Useful for external code that writes to the standard output.
    ///
    /// **Note:** The internal lock is held while `f` is executed. Other threads trying to print
    /// anything on the progress bar will be blocked until `f` finishes.
    /// Therefore, it is recommended to avoid long-running operations in `f`.
    ///
    /// ```rust,no_run
    /// # use indicatif::ProgressBar;
    /// let mut pb = ProgressBar::new(3);
    /// pb.suspend(|| {
    ///     println!("Log message");
    /// })
    /// ```
    pub fn suspend<F: FnOnce() -> R, R>(&self, f: F) -> R {
        self.state().suspend(Instant::now(), f)
    }

    /// Wraps an [`Iterator`] with the progress bar
    ///
    /// ```rust,no_run
    /// # use indicatif::ProgressBar;
    /// let v = vec![1, 2, 3];
    /// let pb = ProgressBar::new(3);
    /// for item in pb.wrap_iter(v.iter()) {
    ///     // ...
    /// }
    /// ```
    pub fn wrap_iter<It: Iterator>(&self, it: It) -> ProgressBarIter<It> {
        it.progress_with(self.clone())
    }

    /// Wraps an [`io::Read`] with the progress bar
    ///
    /// ```rust,no_run
    /// # use std::fs::File;
    /// # use std::io;
    /// # use indicatif::ProgressBar;
    /// # fn test () -> io::Result<()> {
    /// let source = File::open("work.txt")?;
    /// let mut target = File::create("done.txt")?;
    /// let pb = ProgressBar::new(source.metadata()?.len());
    /// io::copy(&mut pb.wrap_read(source), &mut target);
    /// # Ok(())
    /// # }
    /// ```
    pub fn wrap_read<R: io::Read>(&self, read: R) -> ProgressBarIter<R> {
        ProgressBarIter {
            progress: self.clone(),
            it: read,
        }
    }

    /// Wraps an [`io::Write`] with the progress bar
    ///
    /// ```rust,no_run
    /// # use std::fs::File;
    /// # use std::io;
    /// # use indicatif::ProgressBar;
    /// # fn test () -> io::Result<()> {
    /// let mut source = File::open("work.txt")?;
    /// let target = File::create("done.txt")?;
    /// let pb = ProgressBar::new(source.metadata()?.len());
    /// io::copy(&mut source, &mut pb.wrap_write(target));
    /// # Ok(())
    /// # }
    /// ```
    pub fn wrap_write<W: io::Write>(&self, write: W) -> ProgressBarIter<W> {
        ProgressBarIter {
            progress: self.clone(),
            it: write,
        }
    }

    #[cfg(feature = "tokio")]
    #[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
    /// Wraps an [`tokio::io::AsyncWrite`] with the progress bar
    ///
    /// ```rust,no_run
    /// # use tokio::fs::File;
    /// # use tokio::io;
    /// # use indicatif::ProgressBar;
    /// # async fn test() -> io::Result<()> {
    /// let mut source = File::open("work.txt").await?;
    /// let mut target = File::open("done.txt").await?;
    /// let pb = ProgressBar::new(source.metadata().await?.len());
    /// io::copy(&mut source, &mut pb.wrap_async_write(target)).await?;
    /// # Ok(())
    /// # }
    /// ```
    pub fn wrap_async_write<W: tokio::io::AsyncWrite + Unpin>(
        &self,
        write: W,
    ) -> ProgressBarIter<W> {
        ProgressBarIter {
            progress: self.clone(),
            it: write,
        }
    }

    #[cfg(feature = "tokio")]
    #[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
    /// Wraps an [`tokio::io::AsyncRead`] with the progress bar
    ///
    /// ```rust,no_run
    /// # use tokio::fs::File;
    /// # use tokio::io;
    /// # use indicatif::ProgressBar;
    /// # async fn test() -> io::Result<()> {
    /// let mut source = File::open("work.txt").await?;
    /// let mut target = File::open("done.txt").await?;
    /// let pb = ProgressBar::new(source.metadata().await?.len());
    /// io::copy(&mut pb.wrap_async_read(source), &mut target).await?;
    /// # Ok(())
    /// # }
    /// ```
    pub fn wrap_async_read<W: tokio::io::AsyncRead + Unpin>(&self, write: W) -> ProgressBarIter<W> {
        ProgressBarIter {
            progress: self.clone(),
            it: write,
        }
    }

    /// Returns the current position
    pub fn position(&self) -> u64 {
        self.state().state.pos()
    }

    /// Returns the current length
    pub fn length(&self) -> Option<u64> {
        self.state().state.len()
    }

    /// Returns the current ETA
    pub fn eta(&self) -> Duration {
        self.state().state.eta()
    }

    /// Returns the current rate of progress
    pub fn per_sec(&self) -> f64 {
        self.state().state.per_sec()
    }

    /// Returns the current expected duration
    pub fn duration(&self) -> Duration {
        self.state().state.duration()
    }

    /// Returns the current elapsed time
    pub fn elapsed(&self) -> Duration {
        self.state().state.elapsed()
    }

    /// Index in the `MultiState`
    pub(crate) fn index(&self) -> Option<usize> {
        self.state().draw_target.remote().map(|(_, idx)| idx)
    }

    /// Current message
    pub fn message(&self) -> String {
        self.state().state.message.expanded().to_string()
    }

    /// Current prefix
    pub fn prefix(&self) -> String {
        self.state().state.prefix.expanded().to_string()
    }

    #[inline]
    pub(crate) fn state(&self) -> MutexGuard<'_, BarState> {
        self.state.lock().unwrap()
    }
}

/// A weak reference to a `ProgressBar`.
///
/// Useful for creating custom steady tick implementations
#[derive(Clone, Default)]
pub struct WeakProgressBar {
    state: Weak<Mutex<BarState>>,
    pos: Weak<AtomicPosition>,
    ticker: Weak<Mutex<Option<Ticker>>>,
}

impl WeakProgressBar {
    /// Create a new `WeakProgressBar` that returns `None` when [`upgrade`] is called.
    ///
    /// [`upgrade`]: WeakProgressBar::upgrade
    pub fn new() -> WeakProgressBar {
        Default::default()
    }

    /// Attempts to upgrade the Weak pointer to a [`ProgressBar`], delaying dropping of the inner
    /// value if successful. Returns `None` if the inner value has since been dropped.
    ///
    /// [`ProgressBar`]: struct.ProgressBar.html
    pub fn upgrade(&self) -> Option<ProgressBar> {
        let state = self.state.upgrade()?;
        let pos = self.pos.upgrade()?;
        let ticker = self.ticker.upgrade()?;
        Some(ProgressBar { state, pos, ticker })
    }
}

pub(crate) struct Ticker {
    stopping: Arc<(Mutex<bool>, Condvar)>,
    join_handle: Option<thread::JoinHandle<()>>,
}

impl Drop for Ticker {
    fn drop(&mut self) {
        self.stop();
        self.join_handle.take().map(|handle| handle.join());
    }
}

#[cfg(test)]
static TICKER_RUNNING: AtomicBool = AtomicBool::new(false);

impl Ticker {
    pub(crate) fn new(interval: Duration, bar_state: &Arc<Mutex<BarState>>) -> Self {
        debug_assert!(!interval.is_zero());

        // A `Mutex<bool>` is used as a flag to indicate whether the ticker was requested to stop.
        // The `Condvar` is used a notification mechanism: when the ticker is dropped, we notify
        // the thread and interrupt the ticker wait.
        #[allow(clippy::mutex_atomic)]
        let stopping = Arc::new((Mutex::new(false), Condvar::new()));
        let control = TickerControl {
            stopping: stopping.clone(),
            state: Arc::downgrade(bar_state),
        };

        let join_handle = thread::spawn(move || control.run(interval));
        Self {
            stopping,
            join_handle: Some(join_handle),
        }
    }

    pub(crate) fn stop(&self) {
        *self.stopping.0.lock().unwrap() = true;
        self.stopping.1.notify_one();
    }
}

struct TickerControl {
    stopping: Arc<(Mutex<bool>, Condvar)>,
    state: Weak<Mutex<BarState>>,
}

impl TickerControl {
    fn run(&self, interval: Duration) {
        #[cfg(test)]
        TICKER_RUNNING.store(true, Ordering::SeqCst);

        while let Some(arc) = self.state.upgrade() {
            let mut state = arc.lock().unwrap();
            if state.state.is_finished() {
                break;
            }

            state.state.tick = state.state.tick.saturating_add(1);
            state.draw(false, Instant::now()).ok();

            drop(state); // Don't forget to drop the lock before sleeping
            drop(arc); // Also need to drop Arc otherwise BarState won't be dropped

            // Wait for `interval` but return early if we are notified to stop
            let (_, result) = self
                .stopping
                .1
                .wait_timeout_while(self.stopping.0.lock().unwrap(), interval, |stopped| {
                    !*stopped
                })
                .unwrap();

            // If the wait didn't time out, it means we were notified to stop
            if !result.timed_out() {
                break;
            }
        }

        #[cfg(test)]
        TICKER_RUNNING.store(false, Ordering::SeqCst);
    }
}

// Tests using the global TICKER_RUNNING flag need to be serialized
#[cfg(test)]
pub(crate) static TICKER_TEST: Lazy<Mutex<()>> = Lazy::new(Mutex::default);

#[cfg(test)]
mod tests {
    use super::*;

    #[allow(clippy::float_cmp)]
    #[test]
    fn test_pbar_zero() {
        let pb = ProgressBar::new(0);
        assert_eq!(pb.state().state.fraction(), 1.0);
    }

    #[allow(clippy::float_cmp)]
    #[test]
    fn test_pbar_maxu64() {
        let pb = ProgressBar::new(!0);
        assert_eq!(pb.state().state.fraction(), 0.0);
    }

    #[test]
    fn test_pbar_overflow() {
        let pb = ProgressBar::new(1);
        pb.set_draw_target(ProgressDrawTarget::hidden());
        pb.inc(2);
        pb.finish();
    }

    #[test]
    fn test_get_position() {
        let pb = ProgressBar::new(1);
        pb.set_draw_target(ProgressDrawTarget::hidden());
        pb.inc(2);
        let pos = pb.position();
        assert_eq!(pos, 2);
    }

    #[test]
    fn test_weak_pb() {
        let pb = ProgressBar::new(0);
        let weak = pb.downgrade();
        assert!(weak.upgrade().is_some());
        ::std::mem::drop(pb);
        assert!(weak.upgrade().is_none());
    }

    #[test]
    fn it_can_wrap_a_reader() {
        let bytes = &b"I am an implementation of io::Read"[..];
        let pb = ProgressBar::new(bytes.len() as u64);
        let mut reader = pb.wrap_read(bytes);
        let mut writer = Vec::new();
        io::copy(&mut reader, &mut writer).unwrap();
        assert_eq!(writer, bytes);
    }

    #[test]
    fn it_can_wrap_a_writer() {
        let bytes = b"implementation of io::Read";
        let mut reader = &bytes[..];
        let pb = ProgressBar::new(bytes.len() as u64);
        let writer = Vec::new();
        let mut writer = pb.wrap_write(writer);
        io::copy(&mut reader, &mut writer).unwrap();
        assert_eq!(writer.it, bytes);
    }

    #[test]
    fn ticker_thread_terminates_on_drop() {
        let _guard = TICKER_TEST.lock().unwrap();
        assert!(!TICKER_RUNNING.load(Ordering::SeqCst));

        let pb = ProgressBar::new_spinner();
        pb.enable_steady_tick(Duration::from_millis(50));

        // Give the thread time to start up
        thread::sleep(Duration::from_millis(250));

        assert!(TICKER_RUNNING.load(Ordering::SeqCst));

        drop(pb);
        assert!(!TICKER_RUNNING.load(Ordering::SeqCst));
    }

    #[test]
    fn ticker_thread_terminates_on_drop_2() {
        let _guard = TICKER_TEST.lock().unwrap();
        assert!(!TICKER_RUNNING.load(Ordering::SeqCst));

        let pb = ProgressBar::new_spinner();
        pb.enable_steady_tick(Duration::from_millis(50));
        let pb2 = pb.clone();

        // Give the thread time to start up
        thread::sleep(Duration::from_millis(250));

        assert!(TICKER_RUNNING.load(Ordering::SeqCst));

        drop(pb);
        assert!(TICKER_RUNNING.load(Ordering::SeqCst));

        drop(pb2);
        assert!(!TICKER_RUNNING.load(Ordering::SeqCst));
    }
}
