use std::fs::OpenOptions;
use std::io::{self, Write};
use std::path::Path;
use std::sync::{self, Arc, Mutex};
use tracing_subscriber::fmt::writer::BoxMakeWriter;
pub static SHOULD_TRACE: sync::LazyLock<bool> = sync::LazyLock::new(
|| matches!(std::env::var("DEBUG"), Ok(value) if value.eq("*") || (value.contains("tailwindcss:oxide") && !value.contains("-tailwindcss:oxide"))),
);
fn dim(input: &str) -> String {
format!("\u{001b}[2m{input}\u{001b}[22m")
}
fn blue(input: &str) -> String {
format!("\u{001b}[34m{input}\u{001b}[39m")
}
fn highlight(input: &str) -> String {
format!("{}{}{}", dim(&blue("`")), blue(input), dim(&blue("`")))
}
struct MutexWriter(Arc<Mutex<std::fs::File>>);
impl Write for MutexWriter {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.0.lock().unwrap().write(buf)
}
fn flush(&mut self) -> io::Result<()> {
self.0.lock().unwrap().flush()
}
}
pub fn init_tracing() {
if !*SHOULD_TRACE {
return;
}
let file_path = format!("tailwindcss-{}.log", std::process::id());
let file = OpenOptions::new()
.create(true)
.append(true)
.open(&file_path)
.unwrap_or_else(|_| panic!("Failed to open {file_path}"));
let file_path = Path::new(&file_path);
let absolute_file_path = dunce::canonicalize(file_path)
.unwrap_or_else(|_| panic!("Failed to canonicalize {file_path:?}"));
eprintln!(
"{} Writing debug info to: {}\n",
dim("[DEBUG]"),
highlight(absolute_file_path.as_path().to_str().unwrap())
);
let file = Arc::new(Mutex::new(file));
let writer: BoxMakeWriter = BoxMakeWriter::new({
let file = file.clone();
move || Box::new(MutexWriter(file.clone())) as Box<dyn Write + Send>
});
_ = tracing_subscriber::fmt()
.with_max_level(tracing::Level::INFO)
.with_span_events(tracing_subscriber::fmt::format::FmtSpan::ACTIVE)
.with_writer(writer)
.with_ansi(false)
.compact()
.try_init();
}