//! This crate allows tools to enable rust logging without having to magically
//! match rustc's tracing crate version.
//!
//! For example if someone is working on rustc_ast and wants to write some
//! minimal code against it to run in a debugger, with access to the `debug!`
//! logs emitted by rustc_ast, that can be done by writing:
//!
//! ```toml
//! [dependencies]
//! rustc_ast = { path = "../rust/compiler/rustc_ast" }
//! rustc_log = { path = "../rust/compiler/rustc_log" }
//! ```
//!
//! ```
//! fn main() {
//!     rustc_log::init_logger(rustc_log::LoggerConfig::from_env("LOG")).unwrap();
//!     /* ... */
//! }
//! ```
//!
//! Now `LOG=debug cargo +nightly run` will run your minimal main.rs and show
//! rustc's debug logging. In a workflow like this, one might also add
//! `std::env::set_var("LOG", "debug")` to the top of main so that `cargo
//! +nightly run` by itself is sufficient to get logs.
//!
//! The reason rustc_log is a tiny separate crate, as opposed to exposing the
//! same things in rustc_driver only, is to enable the above workflow. If you
//! had to depend on rustc_driver in order to turn on rustc's debug logs, that's
//! an enormously bigger dependency tree; every change you make to rustc_ast (or
//! whichever piece of the compiler you are interested in) would involve
//! rebuilding all the rest of rustc up to rustc_driver in order to run your
//! main.rs. Whereas by depending only on rustc_log and the few crates you are
//! debugging, you can make changes inside those crates and quickly run main.rs
//! to read the debug logs.

use std::cell::Cell;
use std::env::{self, VarError};
use std::fmt::{self, Display};
use std::fs::File;
use std::io::{self, IsTerminal};
use std::sync::Mutex;

use tracing::dispatcher::SetGlobalDefaultError;
use tracing::{Event, Subscriber, span};
use tracing_subscriber::filter::{Directive, EnvFilter, LevelFilter};
use tracing_subscriber::fmt::FmtContext;
use tracing_subscriber::fmt::format::{self, FmtSpan, FormatEvent, FormatFields};
use tracing_subscriber::fmt::writer::BoxMakeWriter;
use tracing_subscriber::layer::{Context, SubscriberExt};
use tracing_subscriber::{Layer, Registry};
// Re-export tracing
pub use {tracing, tracing_core, tracing_subscriber};

/// The values of all the environment variables that matter for configuring a logger.
/// Errors are explicitly preserved so that we can share error handling.
pub struct LoggerConfig {
    pub filter: Result<String, VarError>,
    pub color_logs: Result<String, VarError>,
    pub verbose_entry_exit: Result<String, VarError>,
    pub verbose_thread_ids: Result<String, VarError>,
    pub backtrace: Result<String, VarError>,
    pub json: Result<String, VarError>,
    pub output_target: Result<String, VarError>,
    pub wraptree: Result<String, VarError>,
    pub lines: Result<String, VarError>,
}

impl LoggerConfig {
    pub fn from_env(env: &str) -> Self {
        // NOTE: documented in the dev guide. If you change this, also update it!
        LoggerConfig {
            filter: env::var(env),
            color_logs: env::var(format!("{env}_COLOR")),
            verbose_entry_exit: env::var(format!("{env}_ENTRY_EXIT")),
            verbose_thread_ids: env::var(format!("{env}_THREAD_IDS")),
            backtrace: env::var(format!("{env}_BACKTRACE")),
            wraptree: env::var(format!("{env}_WRAPTREE")),
            lines: env::var(format!("{env}_LINES")),
            json: env::var(format!("{env}_FORMAT_JSON")),
            output_target: env::var(format!("{env}_OUTPUT_TARGET")),
        }
    }
}

/// Initialize the logger with the given values for the filter, coloring, and other options env variables.
pub fn init_logger(cfg: LoggerConfig) -> Result<(), Error> {
    init_logger_with_additional_layer(cfg, Registry::default)
}

/// Trait alias for the complex return type of `build_subscriber` in
/// [init_logger_with_additional_layer]. A [Registry] with any composition of [tracing::Subscriber]s
/// (e.g. `Registry::default().with(custom_layer)`) should be compatible with this type.
/// Having an alias is also useful so rustc_driver_impl does not need to explicitly depend on
/// `tracing_subscriber`.
pub trait BuildSubscriberRet:
    tracing::Subscriber + for<'span> tracing_subscriber::registry::LookupSpan<'span> + Send + Sync
{
}

impl<
    T: tracing::Subscriber + for<'span> tracing_subscriber::registry::LookupSpan<'span> + Send + Sync,
> BuildSubscriberRet for T
{
}

/// Initialize the logger with the given values for the filter, coloring, and other options env variables.
/// Additionally add a custom layer to collect logging and tracing events via `build_subscriber`,
/// for example: `|| Registry::default().with(custom_layer)`.
pub fn init_logger_with_additional_layer<F, T>(
    cfg: LoggerConfig,
    build_subscriber: F,
) -> Result<(), Error>
where
    F: FnOnce() -> T,
    T: BuildSubscriberRet,
{
    let filter = match cfg.filter {
        Ok(env) => EnvFilter::new(env),
        _ => EnvFilter::default().add_directive(Directive::from(LevelFilter::WARN)),
    };

    let color_logs = match cfg.color_logs {
        Ok(value) => match value.as_ref() {
            "always" => true,
            "never" => false,
            "auto" => stderr_isatty(),
            _ => return Err(Error::InvalidColorValue(value)),
        },
        Err(VarError::NotPresent) => stderr_isatty(),
        Err(VarError::NotUnicode(_value)) => return Err(Error::NonUnicodeColorValue),
    };

    let verbose_entry_exit = match cfg.verbose_entry_exit {
        Ok(v) => &v != "0",
        Err(_) => false,
    };

    let verbose_thread_ids = match cfg.verbose_thread_ids {
        Ok(v) => &v == "1",
        Err(_) => false,
    };

    let lines = match cfg.lines {
        Ok(v) => &v == "1",
        Err(_) => false,
    };

    let json = match cfg.json {
        Ok(v) => &v == "1",
        Err(_) => false,
    };

    let output_target: BoxMakeWriter = match cfg.output_target {
        Ok(v) => match File::options().create(true).write(true).truncate(true).open(&v) {
            Ok(i) => BoxMakeWriter::new(Mutex::new(i)),
            Err(e) => {
                eprintln!("couldn't open {v} as a log target: {e:?}");
                BoxMakeWriter::new(io::stderr)
            }
        },
        Err(_) => BoxMakeWriter::new(io::stderr),
    };

    let layer = if json {
        let format = tracing_subscriber::fmt::format()
            .json()
            .with_span_list(true)
            .with_source_location(true);

        let fmt_layer = tracing_subscriber::fmt::layer()
            .json()
            .event_format(format)
            .with_writer(output_target)
            .with_target(true)
            .with_ansi(false)
            .with_thread_ids(verbose_thread_ids)
            .with_thread_names(verbose_thread_ids)
            .with_span_events(FmtSpan::ACTIVE);
        let fmt_layer = NonrecursiveLayer { inner: fmt_layer };
        Layer::boxed(fmt_layer)
    } else {
        let mut layer = tracing_tree::HierarchicalLayer::default()
            .with_writer(output_target)
            .with_ansi(color_logs)
            .with_targets(true)
            .with_verbose_exit(verbose_entry_exit)
            .with_verbose_entry(verbose_entry_exit)
            .with_indent_amount(2)
            .with_indent_lines(lines)
            .with_thread_ids(verbose_thread_ids)
            .with_thread_names(verbose_thread_ids);

        if let Ok(v) = cfg.wraptree {
            match v.parse::<usize>() {
                Ok(v) => layer = layer.with_wraparound(v),
                Err(_) => return Err(Error::InvalidWraptree(v)),
            }
        }

        Layer::boxed(layer)
    };

    let subscriber = build_subscriber();
    // NOTE: It is important to make sure that the filter is applied on the last layer
    match cfg.backtrace {
        Ok(backtrace_target) => {
            let fmt_layer = tracing_subscriber::fmt::layer()
                .with_writer(io::stderr)
                .without_time()
                .event_format(BacktraceFormatter { backtrace_target });
            let subscriber = subscriber.with(layer).with(fmt_layer).with(filter);
            tracing::subscriber::set_global_default(subscriber)?;
        }
        Err(_) => {
            tracing::subscriber::set_global_default(subscriber.with(layer).with(filter))?;
        }
    };

    Ok(())
}

struct BacktraceFormatter {
    backtrace_target: String,
}

impl<S, N> FormatEvent<S, N> for BacktraceFormatter
where
    S: Subscriber + for<'a> tracing_subscriber::registry::LookupSpan<'a>,
    N: for<'a> FormatFields<'a> + 'static,
{
    fn format_event(
        &self,
        _ctx: &FmtContext<'_, S, N>,
        mut writer: format::Writer<'_>,
        event: &Event<'_>,
    ) -> fmt::Result {
        let target = event.metadata().target();
        if !target.contains(&self.backtrace_target) {
            return Ok(());
        }
        // Use Backtrace::force_capture because we don't want to depend on the
        // RUST_BACKTRACE environment variable being set.
        let backtrace = std::backtrace::Backtrace::force_capture();
        writeln!(writer, "stack backtrace: \n{backtrace:?}")
    }
}

pub fn stdout_isatty() -> bool {
    io::stdout().is_terminal()
}

pub fn stderr_isatty() -> bool {
    io::stderr().is_terminal()
}

#[derive(Debug)]
pub enum Error {
    InvalidColorValue(String),
    NonUnicodeColorValue,
    InvalidWraptree(String),
    AlreadyInit(SetGlobalDefaultError),
}

impl std::error::Error for Error {}

impl Display for Error {
    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self {
            Error::InvalidColorValue(value) => write!(
                formatter,
                "invalid log color value '{value}': expected one of always, never, or auto",
            ),
            Error::NonUnicodeColorValue => write!(
                formatter,
                "non-Unicode log color value: expected one of always, never, or auto",
            ),
            Error::InvalidWraptree(value) => write!(
                formatter,
                "invalid log WRAPTREE value '{value}': expected a non-negative integer",
            ),
            Error::AlreadyInit(tracing_error) => Display::fmt(tracing_error, formatter),
        }
    }
}

impl From<SetGlobalDefaultError> for Error {
    fn from(tracing_error: SetGlobalDefaultError) -> Self {
        Error::AlreadyInit(tracing_error)
    }
}

thread_local! {
    static NONRECURSIVE_GUARD_LOCK: Cell<bool> = const { Cell::new(false) };
}

struct NonrecursiveGuard;

impl NonrecursiveGuard {
    fn lock() -> Option<NonrecursiveGuard> {
        if !NONRECURSIVE_GUARD_LOCK.replace(true) { Some(NonrecursiveGuard) } else { None }
    }
}

impl Drop for NonrecursiveGuard {
    fn drop(&mut self) {
        NONRECURSIVE_GUARD_LOCK.set(false);
    }
}

/// Many debug messages that rustc emits produce additional debug messages when formatting the
/// arguments to the original debug message. [`tracing_tree::HierarchicalLayer`] (used by the
/// default output format) filters these out, but [`tracing_subscriber::fmt::format::Json`] (used by
/// `RUSTC_LOG_FORMAT_JSON`) does not. So, implement a simple recursion check to filter these
/// messages out.
struct NonrecursiveLayer<S> {
    inner: S,
}

impl<S: Subscriber, L: Layer<S>> Layer<S> for NonrecursiveLayer<L> {
    fn on_register_dispatch(&self, subscriber: &tracing::Dispatch) {
        self.inner.on_register_dispatch(subscriber)
    }

    fn on_layer(&mut self, subscriber: &mut S) {
        self.inner.on_layer(subscriber)
    }

    fn register_callsite(
        &self,
        metadata: &'static tracing::Metadata<'static>,
    ) -> tracing_core::Interest {
        self.inner.register_callsite(metadata)
    }

    fn enabled(&self, metadata: &tracing::Metadata<'_>, ctx: Context<'_, S>) -> bool {
        self.inner.enabled(metadata, ctx)
    }

    fn on_new_span(&self, attrs: &span::Attributes<'_>, id: &span::Id, ctx: Context<'_, S>) {
        if let Some(_) = NonrecursiveGuard::lock() {
            self.inner.on_new_span(attrs, id, ctx)
        }
    }

    fn on_record(&self, span: &span::Id, values: &span::Record<'_>, ctx: Context<'_, S>) {
        if let Some(_) = NonrecursiveGuard::lock() {
            self.inner.on_record(span, values, ctx)
        }
    }

    fn on_follows_from(&self, span: &span::Id, follows: &span::Id, ctx: Context<'_, S>) {
        if let Some(_) = NonrecursiveGuard::lock() {
            self.inner.on_follows_from(span, follows, ctx)
        }
    }

    fn event_enabled(&self, event: &Event<'_>, ctx: Context<'_, S>) -> bool {
        if let Some(_) = NonrecursiveGuard::lock() {
            self.inner.event_enabled(event, ctx)
        } else {
            false
        }
    }

    fn on_event(&self, event: &Event<'_>, ctx: Context<'_, S>) {
        if let Some(_) = NonrecursiveGuard::lock() {
            self.inner.on_event(event, ctx)
        }
    }

    fn on_enter(&self, id: &span::Id, ctx: Context<'_, S>) {
        if let Some(_) = NonrecursiveGuard::lock() {
            self.inner.on_enter(id, ctx)
        }
    }

    fn on_exit(&self, id: &span::Id, ctx: Context<'_, S>) {
        if let Some(_) = NonrecursiveGuard::lock() {
            self.inner.on_exit(id, ctx)
        }
    }

    fn on_close(&self, id: span::Id, ctx: Context<'_, S>) {
        if let Some(_) = NonrecursiveGuard::lock() {
            self.inner.on_close(id, ctx)
        }
    }

    fn on_id_change(&self, old: &span::Id, new: &span::Id, ctx: Context<'_, S>) {
        self.inner.on_id_change(old, new, ctx)
    }
}
