use std::{
    borrow::Cow,
    collections::HashMap,
    fmt, fs,
    io::{self, BufWriter, Write},
    sync::{mpsc, Arc, Mutex},
};

#[cfg(feature = "date-based")]
use std::{
    ffi::OsString,
    fs::OpenOptions,
    path::{Path, PathBuf},
};

use log::{self, Log};

use crate::{Filter, Formatter};

#[cfg(all(not(windows), feature = "syslog-4"))]
use crate::{Syslog4Rfc3164Logger, Syslog4Rfc5424Logger, Syslog4TransformFn};
#[cfg(all(not(windows), feature = "syslog-6"))]
use crate::{Syslog6Rfc3164Logger, Syslog6Rfc5424Logger, Syslog6TransformFn};

pub enum LevelConfiguration {
    JustDefault,
    Minimal(Vec<(Cow<'static, str>, log::LevelFilter)>),
    Many(HashMap<Cow<'static, str>, log::LevelFilter>),
}

pub struct Dispatch {
    pub output: Vec<Output>,
    pub default_level: log::LevelFilter,
    pub levels: LevelConfiguration,
    pub format: Option<Box<Formatter>>,
    pub filters: Vec<Box<Filter>>,
}

/// Callback struct for use within a formatter closure
///
/// Callbacks are used for formatting in order to allow usage of
/// [`std::fmt`]-based formatting without the allocation of the formatted
/// result which would be required to return it.
///
/// Example usage:
///
/// ```
/// fern::Dispatch::new().format(|callback: fern::FormatCallback, message, record| {
///     callback.finish(format_args!("[{}] {}", record.level(), message))
/// })
/// # ;
/// ```
///
/// [`std::fmt`]: https://doc.rust-lang.org/std/fmt/index.html
#[must_use = "format callback must be used for log to process correctly"]
pub struct FormatCallback<'a>(InnerFormatCallback<'a>);

struct InnerFormatCallback<'a>(&'a mut bool, &'a Dispatch, &'a log::Record<'a>);

pub enum Output {
    Stdout(Stdout),
    Stderr(Stderr),
    File(File),
    Sender(Sender),
    #[cfg(all(not(windows), feature = "syslog-3"))]
    Syslog3(Syslog3),
    #[cfg(all(not(windows), feature = "syslog-4"))]
    Syslog4Rfc3164(Syslog4Rfc3164),
    #[cfg(all(not(windows), feature = "syslog-4"))]
    Syslog4Rfc5424(Syslog4Rfc5424),
    #[cfg(all(not(windows), feature = "syslog-6"))]
    Syslog6Rfc3164(Syslog6Rfc3164),
    #[cfg(all(not(windows), feature = "syslog-6"))]
    Syslog6Rfc5424(Syslog6Rfc5424),
    Dispatch(Dispatch),
    SharedDispatch(Arc<Dispatch>),
    OtherBoxed(Box<dyn Log>),
    OtherStatic(&'static dyn Log),
    Panic(Panic),
    Writer(Writer),
    #[cfg(feature = "date-based")]
    DateBased(DateBased),
    #[cfg(all(not(windows), feature = "reopen-03"))]
    Reopen(Reopen),
    #[cfg(all(not(windows), feature = "reopen-1"))]
    Reopen1(Reopen1),
}

pub struct Stdout {
    pub stream: io::Stdout,
    pub line_sep: Cow<'static, str>,
}

pub struct Stderr {
    pub stream: io::Stderr,
    pub line_sep: Cow<'static, str>,
}

pub struct File {
    pub stream: Mutex<BufWriter<fs::File>>,
    pub line_sep: Cow<'static, str>,
}

pub struct Sender {
    pub stream: Mutex<mpsc::Sender<String>>,
    pub line_sep: Cow<'static, str>,
}

pub struct Writer {
    pub stream: Mutex<Box<dyn Write + Send>>,
    pub line_sep: Cow<'static, str>,
}

#[cfg(all(not(windows), feature = "reopen-03"))]
pub struct Reopen {
    pub stream: Mutex<reopen03::Reopen<fs::File>>,
    pub line_sep: Cow<'static, str>,
}

#[cfg(all(not(windows), feature = "reopen-1"))]
pub struct Reopen1 {
    pub stream: Mutex<reopen1::Reopen<fs::File>>,
    pub line_sep: Cow<'static, str>,
}

#[cfg(all(not(windows), feature = "syslog-3"))]
pub struct Syslog3 {
    pub inner: syslog3::Logger,
}

#[cfg(all(not(windows), feature = "syslog-4"))]
pub struct Syslog4Rfc3164 {
    pub inner: Mutex<Syslog4Rfc3164Logger>,
}

#[cfg(all(not(windows), feature = "syslog-4"))]
pub struct Syslog4Rfc5424 {
    pub inner: Mutex<Syslog4Rfc5424Logger>,
    pub transform: Box<Syslog4TransformFn>,
}

#[cfg(all(not(windows), feature = "syslog-6"))]
pub struct Syslog6Rfc3164 {
    pub inner: Mutex<Syslog6Rfc3164Logger>,
}

#[cfg(all(not(windows), feature = "syslog-6"))]
pub struct Syslog6Rfc5424 {
    pub inner: Mutex<Syslog6Rfc5424Logger>,
    pub transform: Box<Syslog6TransformFn>,
}

pub struct Panic;

pub struct Null;

/// File logger with a dynamic time-based name.
#[derive(Debug)]
#[cfg(feature = "date-based")]
pub struct DateBased {
    pub config: DateBasedConfig,
    pub state: Mutex<DateBasedState>,
}

#[derive(Debug)]
#[cfg(feature = "date-based")]
pub enum ConfiguredTimezone {
    Local,
    Utc,
}

#[derive(Debug)]
#[cfg(feature = "date-based")]
pub struct DateBasedConfig {
    pub line_sep: Cow<'static, str>,
    /// This is a Path not an str so it can hold invalid UTF8 paths correctly.
    pub file_prefix: PathBuf,
    pub file_suffix: Cow<'static, str>,
    pub timezone: ConfiguredTimezone,
}

#[derive(Debug)]
#[cfg(feature = "date-based")]
pub struct DateBasedState {
    pub current_suffix: String,
    pub file_stream: Option<BufWriter<fs::File>>,
}

#[cfg(feature = "date-based")]
impl DateBasedState {
    pub fn new(current_suffix: String, file_stream: Option<fs::File>) -> Self {
        DateBasedState {
            current_suffix,
            file_stream: file_stream.map(BufWriter::new),
        }
    }

    pub fn replace_file(&mut self, new_suffix: String, new_file: Option<fs::File>) {
        if let Some(mut old) = self.file_stream.take() {
            let _ = old.flush();
        }
        self.current_suffix = new_suffix;
        self.file_stream = new_file.map(BufWriter::new)
    }
}

#[cfg(feature = "date-based")]
impl DateBasedConfig {
    pub fn new(
        line_sep: Cow<'static, str>,
        file_prefix: PathBuf,
        file_suffix: Cow<'static, str>,
        timezone: ConfiguredTimezone,
    ) -> Self {
        DateBasedConfig {
            line_sep,
            file_prefix,
            file_suffix,
            timezone,
        }
    }

    pub fn compute_current_suffix(&self) -> String {
        match self.timezone {
            ConfiguredTimezone::Utc => chrono::Utc::now().format(&self.file_suffix).to_string(),
            ConfiguredTimezone::Local => chrono::Local::now().format(&self.file_suffix).to_string(),
        }
    }

    pub fn compute_file_path(&self, suffix: &str) -> PathBuf {
        let mut path = OsString::from(&*self.file_prefix);
        // use the OsString::push method, not PathBuf::push which would add a path
        // separator
        path.push(suffix);
        path.into()
    }

    pub fn open_log_file(path: &Path) -> io::Result<fs::File> {
        OpenOptions::new()
            .write(true)
            .create(true)
            .append(true)
            .open(path)
    }

    pub fn open_current_log_file(&self, suffix: &str) -> io::Result<fs::File> {
        Self::open_log_file(&self.compute_file_path(suffix))
    }
}

impl From<Vec<(Cow<'static, str>, log::LevelFilter)>> for LevelConfiguration {
    fn from(mut levels: Vec<(Cow<'static, str>, log::LevelFilter)>) -> Self {
        // Benchmarked separately: https://gist.github.com/daboross/976978d8200caf86e02acb6805961195
        // Use Vec if there are fewer than 15 items, HashMap if there are more than 15.
        match levels.len() {
            0 => LevelConfiguration::JustDefault,
            x if x > 15 => LevelConfiguration::Many(levels.into_iter().collect()),
            _ => {
                levels.shrink_to_fit();
                LevelConfiguration::Minimal(levels)
            }
        }
    }
}

impl LevelConfiguration {
    // inline since we use it literally once.
    #[inline]
    fn find_module(&self, module: &str) -> Option<log::LevelFilter> {
        match *self {
            LevelConfiguration::JustDefault => None,
            _ => {
                if let Some(level) = self.find_exact(module) {
                    return Some(level);
                }

                // The manual for loop here lets us just iterate over the module string once
                // while still finding each sub-module. For the module string
                // "hyper::http::h1", this loop will test first "hyper::http"
                // then "hyper".
                let mut last_char_colon = false;

                for (index, ch) in module.char_indices().rev() {
                    if last_char_colon {
                        last_char_colon = false;
                        if ch == ':' {
                            let sub_module = &module[0..index];

                            if let Some(level) = self.find_exact(sub_module) {
                                return Some(level);
                            }
                        }
                    } else if ch == ':' {
                        last_char_colon = true;
                    }
                }

                None
            }
        }
    }

    fn find_exact(&self, module: &str) -> Option<log::LevelFilter> {
        match *self {
            LevelConfiguration::JustDefault => None,
            LevelConfiguration::Minimal(ref levels) => levels
                .iter()
                .find(|(test_module, _)| test_module == module)
                .map(|(_, level)| *level),
            LevelConfiguration::Many(ref levels) => levels.get(module).cloned(),
        }
    }
}

impl Log for Output {
    fn enabled(&self, metadata: &log::Metadata) -> bool {
        match *self {
            Output::Stdout(ref s) => s.enabled(metadata),
            Output::Stderr(ref s) => s.enabled(metadata),
            Output::File(ref s) => s.enabled(metadata),
            Output::Sender(ref s) => s.enabled(metadata),
            Output::Dispatch(ref s) => s.enabled(metadata),
            Output::SharedDispatch(ref s) => s.enabled(metadata),
            Output::OtherBoxed(ref s) => s.enabled(metadata),
            Output::OtherStatic(ref s) => s.enabled(metadata),
            #[cfg(all(not(windows), feature = "syslog-3"))]
            Output::Syslog3(ref s) => s.enabled(metadata),
            #[cfg(all(not(windows), feature = "syslog-4"))]
            Output::Syslog4Rfc3164(ref s) => s.enabled(metadata),
            #[cfg(all(not(windows), feature = "syslog-4"))]
            Output::Syslog4Rfc5424(ref s) => s.enabled(metadata),
            #[cfg(all(not(windows), feature = "syslog-6"))]
            Output::Syslog6Rfc3164(ref s) => s.enabled(metadata),
            #[cfg(all(not(windows), feature = "syslog-6"))]
            Output::Syslog6Rfc5424(ref s) => s.enabled(metadata),
            Output::Panic(ref s) => s.enabled(metadata),
            Output::Writer(ref s) => s.enabled(metadata),
            #[cfg(feature = "date-based")]
            Output::DateBased(ref s) => s.enabled(metadata),
            #[cfg(all(not(windows), feature = "reopen-03"))]
            Output::Reopen(ref s) => s.enabled(metadata),
            #[cfg(all(not(windows), feature = "reopen-1"))]
            Output::Reopen1(ref s) => s.enabled(metadata),
        }
    }

    fn log(&self, record: &log::Record) {
        match *self {
            Output::Stdout(ref s) => s.log(record),
            Output::Stderr(ref s) => s.log(record),
            Output::File(ref s) => s.log(record),
            Output::Sender(ref s) => s.log(record),
            Output::Dispatch(ref s) => s.log(record),
            Output::SharedDispatch(ref s) => s.log(record),
            Output::OtherBoxed(ref s) => s.log(record),
            Output::OtherStatic(ref s) => s.log(record),
            #[cfg(all(not(windows), feature = "syslog-3"))]
            Output::Syslog3(ref s) => s.log(record),
            #[cfg(all(not(windows), feature = "syslog-4"))]
            Output::Syslog4Rfc3164(ref s) => s.log(record),
            #[cfg(all(not(windows), feature = "syslog-4"))]
            Output::Syslog4Rfc5424(ref s) => s.log(record),
            #[cfg(all(not(windows), feature = "syslog-6"))]
            Output::Syslog6Rfc3164(ref s) => s.log(record),
            #[cfg(all(not(windows), feature = "syslog-6"))]
            Output::Syslog6Rfc5424(ref s) => s.log(record),
            Output::Panic(ref s) => s.log(record),
            Output::Writer(ref s) => s.log(record),
            #[cfg(feature = "date-based")]
            Output::DateBased(ref s) => s.log(record),
            #[cfg(all(not(windows), feature = "reopen-03"))]
            Output::Reopen(ref s) => s.log(record),
            #[cfg(all(not(windows), feature = "reopen-1"))]
            Output::Reopen1(ref s) => s.log(record),
        }
    }

    fn flush(&self) {
        match *self {
            Output::Stdout(ref s) => s.flush(),
            Output::Stderr(ref s) => s.flush(),
            Output::File(ref s) => s.flush(),
            Output::Sender(ref s) => s.flush(),
            Output::Dispatch(ref s) => s.flush(),
            Output::SharedDispatch(ref s) => s.flush(),
            Output::OtherBoxed(ref s) => s.flush(),
            Output::OtherStatic(ref s) => s.flush(),
            #[cfg(all(not(windows), feature = "syslog-3"))]
            Output::Syslog3(ref s) => s.flush(),
            #[cfg(all(not(windows), feature = "syslog-4"))]
            Output::Syslog4Rfc3164(ref s) => s.flush(),
            #[cfg(all(not(windows), feature = "syslog-4"))]
            Output::Syslog4Rfc5424(ref s) => s.flush(),
            #[cfg(all(not(windows), feature = "syslog-6"))]
            Output::Syslog6Rfc3164(ref s) => s.flush(),
            #[cfg(all(not(windows), feature = "syslog-6"))]
            Output::Syslog6Rfc5424(ref s) => s.flush(),
            Output::Panic(ref s) => s.flush(),
            Output::Writer(ref s) => s.flush(),
            #[cfg(feature = "date-based")]
            Output::DateBased(ref s) => s.flush(),
            #[cfg(all(not(windows), feature = "reopen-03"))]
            Output::Reopen(ref s) => s.flush(),
            #[cfg(all(not(windows), feature = "reopen-1"))]
            Output::Reopen1(ref s) => s.flush(),
        }
    }
}

impl Log for Null {
    fn enabled(&self, _: &log::Metadata) -> bool {
        false
    }

    fn log(&self, _: &log::Record) {}

    fn flush(&self) {}
}

impl Log for Dispatch {
    fn enabled(&self, metadata: &log::Metadata) -> bool {
        self.deep_enabled(metadata)
    }

    fn log(&self, record: &log::Record) {
        if self.shallow_enabled(record.metadata()) {
            match self.format {
                Some(ref format) => {
                    // flag to ensure the log message is completed even if the formatter doesn't
                    // complete the callback.
                    let mut callback_called_flag = false;

                    (format)(
                        FormatCallback(InnerFormatCallback(
                            &mut callback_called_flag,
                            self,
                            record,
                        )),
                        record.args(),
                        record,
                    );

                    if !callback_called_flag {
                        self.finish_logging(record);
                    }
                }
                None => {
                    self.finish_logging(record);
                }
            }
        }
    }

    fn flush(&self) {
        for log in &self.output {
            log.flush();
        }
    }
}

impl Dispatch {
    fn finish_logging(&self, record: &log::Record) {
        for log in &self.output {
            log.log(record);
        }
    }

    /// Check whether this log's filters prevent the given log from happening.
    fn shallow_enabled(&self, metadata: &log::Metadata) -> bool {
        metadata.level()
            <= self
                .levels
                .find_module(metadata.target())
                .unwrap_or(self.default_level)
            && self.filters.iter().all(|f| f(metadata))
    }

    /// Check whether a log with the given metadata would eventually end up
    /// outputting something.
    ///
    /// This is recursive, and checks children.
    fn deep_enabled(&self, metadata: &log::Metadata) -> bool {
        self.shallow_enabled(metadata) && self.output.iter().any(|l| l.enabled(metadata))
    }
}

impl<'a> FormatCallback<'a> {
    /// Complete the formatting call that this FormatCallback was created for.
    ///
    /// This will call the rest of the logging chain using the given formatted
    /// message as the new payload message.
    ///
    /// Example usage:
    ///
    /// ```
    /// # fern::Dispatch::new()
    /// # .format(|callback: fern::FormatCallback, message, record| {
    /// callback.finish(format_args!("[{}] {}", record.level(), message))
    /// # })
    /// # .into_log();
    /// ```
    ///
    /// See [`format_args!`].
    ///
    /// [`format_args!`]: https://doc.rust-lang.org/std/macro.format_args.html
    pub fn finish(self, formatted_message: fmt::Arguments) {
        let FormatCallback(InnerFormatCallback(callback_called_flag, dispatch, record)) = self;

        // let the dispatch know that we did in fact get called.
        *callback_called_flag = true;

        // NOTE: This needs to be updated whenever new things are added to
        // `log::Record`.
        let new_record = log::RecordBuilder::new()
            .args(formatted_message)
            .metadata(record.metadata().clone())
            .level(record.level())
            .target(record.target())
            .module_path(record.module_path())
            .file(record.file())
            .line(record.line())
            .build();

        dispatch.finish_logging(&new_record);
    }
}

// No need to write this twice (used for Stdout and Stderr structs)
macro_rules! std_log_impl {
    ($ident:ident) => {
        impl Log for $ident {
            fn enabled(&self, _: &log::Metadata) -> bool {
                true
            }

            fn log(&self, record: &log::Record) {
                fallback_on_error(record, |record| {
                    if cfg!(feature = "meta-logging-in-format") {
                        // Formatting first prevents deadlocks when the process of formatting
                        // itself is logged. note: this is only ever needed if some
                        // Debug, Display, or other formatting trait itself is
                        // logging things too.
                        let msg = format!("{}{}", record.args(), self.line_sep);

                        write!(self.stream.lock(), "{}", msg)?;
                    } else {
                        write!(self.stream.lock(), "{}{}", record.args(), self.line_sep)?;
                    }

                    Ok(())
                });
            }

            fn flush(&self) {
                let _ = self.stream.lock().flush();
            }
        }
    };
}

std_log_impl!(Stdout);
std_log_impl!(Stderr);

macro_rules! writer_log_impl {
    ($ident:ident) => {
        impl Log for $ident {
            fn enabled(&self, _: &log::Metadata) -> bool {
                true
            }

            fn log(&self, record: &log::Record) {
                fallback_on_error(record, |record| {
                    if cfg!(feature = "meta-logging-in-format") {
                        // Formatting first prevents deadlocks on file-logging,
                        // when the process of formatting itself is logged.
                        // note: this is only ever needed if some Debug, Display, or other
                        // formatting trait itself is logging.
                        let msg = format!("{}{}", record.args(), self.line_sep);

                        let mut writer = self.stream.lock().unwrap_or_else(|e| e.into_inner());

                        write!(writer, "{}", msg)?;

                        writer.flush()?;
                    } else {
                        let mut writer = self.stream.lock().unwrap_or_else(|e| e.into_inner());

                        write!(writer, "{}{}", record.args(), self.line_sep)?;

                        writer.flush()?;
                    }
                    Ok(())
                });
            }

            fn flush(&self) {
                let _ = self
                    .stream
                    .lock()
                    .unwrap_or_else(|e| e.into_inner())
                    .flush();
            }
        }
    };
}

writer_log_impl!(File);
writer_log_impl!(Writer);

#[cfg(all(not(windows), feature = "reopen-03"))]
writer_log_impl!(Reopen);

#[cfg(all(not(windows), feature = "reopen-1"))]
writer_log_impl!(Reopen1);

impl Log for Sender {
    fn enabled(&self, _: &log::Metadata) -> bool {
        true
    }

    fn log(&self, record: &log::Record) {
        fallback_on_error(record, |record| {
            let msg = format!("{}{}", record.args(), self.line_sep);
            self.stream
                .lock()
                .unwrap_or_else(|e| e.into_inner())
                .send(msg)?;
            Ok(())
        });
    }

    fn flush(&self) {}
}

#[cfg(all(
    not(windows),
    any(feature = "syslog-3", feature = "syslog-4", feature = "syslog-6")
))]
macro_rules! send_syslog {
    ($logger:expr, $level:expr, $message:expr) => {
        use log::Level;
        match $level {
            Level::Error => $logger.err($message)?,
            Level::Warn => $logger.warning($message)?,
            Level::Info => $logger.info($message)?,
            Level::Debug | Level::Trace => $logger.debug($message)?,
        }
    };
}

#[cfg(all(not(windows), feature = "syslog-3"))]
impl Log for Syslog3 {
    fn enabled(&self, _: &log::Metadata) -> bool {
        true
    }

    fn log(&self, record: &log::Record) {
        fallback_on_error(record, |record| {
            let message = record.args();
            send_syslog!(self.inner, record.level(), message);

            Ok(())
        });
    }
    fn flush(&self) {}
}

#[cfg(all(not(windows), feature = "syslog-4"))]
impl Log for Syslog4Rfc3164 {
    fn enabled(&self, _: &log::Metadata) -> bool {
        true
    }

    fn log(&self, record: &log::Record) {
        fallback_on_error(record, |record| {
            let message = record.args().to_string();
            let mut log = self.inner.lock().unwrap_or_else(|e| e.into_inner());
            send_syslog!(log, record.level(), message);

            Ok(())
        });
    }
    fn flush(&self) {}
}

#[cfg(all(not(windows), feature = "syslog-4"))]
impl Log for Syslog4Rfc5424 {
    fn enabled(&self, _: &log::Metadata) -> bool {
        true
    }

    fn log(&self, record: &log::Record) {
        fallback_on_error(record, |record| {
            let transformed = (self.transform)(record);
            let mut log = self.inner.lock().unwrap_or_else(|e| e.into_inner());
            send_syslog!(log, record.level(), transformed);

            Ok(())
        });
    }
    fn flush(&self) {}
}

#[cfg(all(not(windows), feature = "syslog-6"))]
impl Log for Syslog6Rfc3164 {
    fn enabled(&self, _: &log::Metadata) -> bool {
        true
    }

    fn log(&self, record: &log::Record) {
        fallback_on_error(record, |record| {
            let message = record.args().to_string();
            let mut log = self.inner.lock().unwrap_or_else(|e| e.into_inner());
            send_syslog!(log, record.level(), message);

            Ok(())
        });
    }
    fn flush(&self) {}
}

#[cfg(all(not(windows), feature = "syslog-6"))]
impl Log for Syslog6Rfc5424 {
    fn enabled(&self, _: &log::Metadata) -> bool {
        true
    }

    fn log(&self, record: &log::Record) {
        fallback_on_error(record, |record| {
            let transformed = (self.transform)(record);
            let mut log = self.inner.lock().unwrap_or_else(|e| e.into_inner());
            send_syslog!(log, record.level(), transformed);

            Ok(())
        });
    }
    fn flush(&self) {}
}

impl Log for Panic {
    fn enabled(&self, _: &log::Metadata) -> bool {
        true
    }

    fn log(&self, record: &log::Record) {
        panic!("{}", record.args());
    }

    fn flush(&self) {}
}

#[cfg(feature = "date-based")]
impl Log for DateBased {
    fn enabled(&self, _: &log::Metadata) -> bool {
        true
    }

    fn log(&self, record: &log::Record) {
        fallback_on_error(record, |record| {
            // Formatting first prevents deadlocks on file-logging,
            // when the process of formatting itself is logged.
            // note: this is only ever needed if some Debug, Display, or other
            // formatting trait itself is logging.
            #[cfg(feature = "meta-logging-in-format")]
            let msg = format!("{}{}", record.args(), self.config.line_sep);

            let mut state = self.state.lock().unwrap_or_else(|e| e.into_inner());

            // check if log needs to be rotated
            let new_suffix = self.config.compute_current_suffix();
            if state.file_stream.is_none() || state.current_suffix != new_suffix {
                let file_open_result = self.config.open_current_log_file(&new_suffix);
                match file_open_result {
                    Ok(file) => {
                        state.replace_file(new_suffix, Some(file));
                    }
                    Err(e) => {
                        state.replace_file(new_suffix, None);
                        return Err(e.into());
                    }
                }
            }

            // either just initialized writer above, or already errored out.
            let writer = state.file_stream.as_mut().unwrap();

            #[cfg(feature = "meta-logging-in-format")]
            write!(writer, "{}", msg)?;
            #[cfg(not(feature = "meta-logging-in-format"))]
            write!(writer, "{}{}", record.args(), self.config.line_sep)?;

            writer.flush()?;

            Ok(())
        });
    }

    fn flush(&self) {
        let mut state = self.state.lock().unwrap_or_else(|e| e.into_inner());

        if let Some(stream) = &mut state.file_stream {
            let _ = stream.flush();
        }
    }
}

#[inline(always)]
fn fallback_on_error<F>(record: &log::Record, log_func: F)
where
    F: FnOnce(&log::Record) -> Result<(), LogError>,
{
    if let Err(error) = log_func(record) {
        backup_logging(record, &error)
    }
}

fn backup_logging(record: &log::Record, error: &LogError) {
    let second = write!(
        io::stderr(),
        "Error performing logging.\
         \n\tattempted to log: {}\
         \n\trecord: {:?}\
         \n\tlogging error: {}",
        record.args(),
        record,
        error
    );

    if let Err(second_error) = second {
        panic!(
            "Error performing stderr logging after error occurred during regular logging.\
             \n\tattempted to log: {}\
             \n\trecord: {:?}\
             \n\tfirst logging error: {}\
             \n\tstderr error: {}",
            record.args(),
            record,
            error,
            second_error,
        );
    }
}

#[derive(Debug)]
enum LogError {
    Io(io::Error),
    Send(mpsc::SendError<String>),
    #[cfg(all(not(windows), feature = "syslog-4"))]
    Syslog4(syslog4::Error),
    #[cfg(all(not(windows), feature = "syslog-6"))]
    Syslog6(syslog6::Error),
}

impl fmt::Display for LogError {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            LogError::Io(ref e) => write!(f, "{}", e),
            LogError::Send(ref e) => write!(f, "{}", e),
            #[cfg(all(not(windows), feature = "syslog-4"))]
            LogError::Syslog4(ref e) => write!(f, "{}", e),
            #[cfg(all(not(windows), feature = "syslog-6"))]
            LogError::Syslog6(ref e) => write!(f, "{}", e),
        }
    }
}

impl From<io::Error> for LogError {
    fn from(error: io::Error) -> Self {
        LogError::Io(error)
    }
}

impl From<mpsc::SendError<String>> for LogError {
    fn from(error: mpsc::SendError<String>) -> Self {
        LogError::Send(error)
    }
}

#[cfg(all(not(windows), feature = "syslog-4"))]
impl From<syslog4::Error> for LogError {
    fn from(error: syslog4::Error) -> Self {
        LogError::Syslog4(error)
    }
}

#[cfg(all(not(windows), feature = "syslog-6"))]
impl From<syslog6::Error> for LogError {
    fn from(error: syslog6::Error) -> Self {
        LogError::Syslog6(error)
    }
}

#[cfg(test)]
mod test {
    use super::LevelConfiguration;
    use log::LevelFilter::*;

    #[test]
    fn test_level_config_find_exact_minimal() {
        let config = LevelConfiguration::Minimal(
            vec![("mod1", Info), ("mod2", Debug), ("mod3", Off)]
                .into_iter()
                .map(|(k, v)| (k.into(), v))
                .collect(),
        );

        assert_eq!(config.find_exact("mod1"), Some(Info));
        assert_eq!(config.find_exact("mod2"), Some(Debug));
        assert_eq!(config.find_exact("mod3"), Some(Off));
    }

    #[test]
    fn test_level_config_find_exact_many() {
        let config = LevelConfiguration::Many(
            vec![("mod1", Info), ("mod2", Debug), ("mod3", Off)]
                .into_iter()
                .map(|(k, v)| (k.into(), v))
                .collect(),
        );

        assert_eq!(config.find_exact("mod1"), Some(Info));
        assert_eq!(config.find_exact("mod2"), Some(Debug));
        assert_eq!(config.find_exact("mod3"), Some(Off));
    }

    #[test]
    fn test_level_config_simple_hierarchy() {
        let config = LevelConfiguration::Minimal(
            vec![("mod1", Info), ("mod2::sub_mod", Debug), ("mod3", Off)]
                .into_iter()
                .map(|(k, v)| (k.into(), v))
                .collect(),
        );

        assert_eq!(config.find_module("mod1::sub_mod"), Some(Info));
        assert_eq!(config.find_module("mod2::sub_mod::sub_mod_2"), Some(Debug));
        assert_eq!(config.find_module("mod3::sub_mod::sub_mod_2"), Some(Off));
    }

    #[test]
    fn test_level_config_hierarchy_correct() {
        let config = LevelConfiguration::Minimal(
            vec![
                ("root", Trace),
                ("root::sub1", Debug),
                ("root::sub2", Info),
                // should work with all insertion orders
                ("root::sub2::sub2.3::sub2.4", Error),
                ("root::sub2::sub2.3", Warn),
                ("root::sub3", Off),
            ]
            .into_iter()
            .map(|(k, v)| (k.into(), v))
            .collect(),
        );

        assert_eq!(config.find_module("root"), Some(Trace));
        assert_eq!(config.find_module("root::other_module"), Some(Trace));

        // We want to ensure that it does pick up most specific level before trying
        // anything more general.
        assert_eq!(config.find_module("root::sub1"), Some(Debug));
        assert_eq!(config.find_module("root::sub1::other_module"), Some(Debug));

        assert_eq!(config.find_module("root::sub2"), Some(Info));
        assert_eq!(config.find_module("root::sub2::other"), Some(Info));

        assert_eq!(config.find_module("root::sub2::sub2.3"), Some(Warn));
        assert_eq!(
            config.find_module("root::sub2::sub2.3::sub2.4"),
            Some(Error)
        );

        assert_eq!(config.find_module("root::sub3"), Some(Off));
        assert_eq!(
            config.find_module("root::sub3::any::children::of::sub3"),
            Some(Off)
        );
    }

    #[test]
    fn test_level_config_similar_names_are_not_same() {
        let config = LevelConfiguration::Minimal(
            vec![("root", Trace), ("rootay", Info)]
                .into_iter()
                .map(|(k, v)| (k.into(), v))
                .collect(),
        );

        assert_eq!(config.find_module("root"), Some(Trace));
        assert_eq!(config.find_module("root::sub"), Some(Trace));
        assert_eq!(config.find_module("rooty"), None);
        assert_eq!(config.find_module("rooty::sub"), None);
        assert_eq!(config.find_module("rootay"), Some(Info));
        assert_eq!(config.find_module("rootay::sub"), Some(Info));
    }

    #[test]
    fn test_level_config_single_colon_is_not_double_colon() {
        let config = LevelConfiguration::Minimal(
            vec![
                ("root", Trace),
                ("root::su", Debug),
                ("root::su:b2", Info),
                ("root::sub2", Warn),
            ]
            .into_iter()
            .map(|(k, v)| (k.into(), v))
            .collect(),
        );

        assert_eq!(config.find_module("root"), Some(Trace));

        assert_eq!(config.find_module("root::su"), Some(Debug));
        assert_eq!(config.find_module("root::su::b2"), Some(Debug));

        assert_eq!(config.find_module("root::su:b2"), Some(Info));
        assert_eq!(config.find_module("root::su:b2::b3"), Some(Info));

        assert_eq!(config.find_module("root::sub2"), Some(Warn));
        assert_eq!(config.find_module("root::sub2::b3"), Some(Warn));
    }

    #[test]
    fn test_level_config_all_chars() {
        let config = LevelConfiguration::Minimal(
            vec![("♲", Trace), ("☸", Debug), ("♲::☸", Info), ("♲::\t", Debug)]
                .into_iter()
                .map(|(k, v)| (k.into(), v))
                .collect(),
        );

        assert_eq!(config.find_module("♲"), Some(Trace));
        assert_eq!(config.find_module("♲::other"), Some(Trace));

        assert_eq!(config.find_module("☸"), Some(Debug));
        assert_eq!(config.find_module("☸::any"), Some(Debug));

        assert_eq!(config.find_module("♲::☸"), Some(Info));
        assert_eq!(config.find_module("♲☸"), None);

        assert_eq!(config.find_module("♲::\t"), Some(Debug));
        assert_eq!(config.find_module("♲::\t::\n\n::\t"), Some(Debug));
        assert_eq!(config.find_module("♲::\t\t"), Some(Trace));
    }
}
