use crate::*;

fn query(query: &str, timeout_ms: u16) -> Result<String, TlError> {
    use crossterm::terminal::*;
    let switch_to_raw = !is_raw_mode_enabled()?;
    if switch_to_raw {
        enable_raw_mode()?;
    }
    let res = xterm_query::query_osc(query, timeout_ms)
        .map_err(|e| e.into());
    if switch_to_raw {
        disable_raw_mode()?;
    }
    res
}

/// Query the bg color, assuming the terminal is in raw mode,
/// using the "dynamic colors" OSC escape sequence.
pub fn query_bg_color() -> Result<Rgb, TlError> {
    // we use the "dynamic colors" OSC escape sequence. It's sent with a ? for
    // a query and normally answered by the terminal with a color.
    // References:
    // - https://stackoverflow.com/a/28334701/263525
    // - https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
    let s = query("\x1b]11;?\x07", 100)?;
    // The string we receive is like `"]11;rgb:<red>/<green>/<blue>\\"`
    // where `<red>`, `<green>`, and `<blue>` are 4 hex digits.
    // Most terminals don't support such precision so they fill the 4 digits
    // by repeating their 2 digits precision.
    // For example, supposing the background is in #38A4C9 (blue),
    // then we receive `"\u{1b}]11;rgb:3838/a4a4/c9c9\u{1b}\\"`.
    // We read only the most significant hex digits which are good enough
    // in all cases.
    match s.strip_prefix("]11;rgb:") {
        Some(raw_color) if raw_color.len() >= 14 => Ok(Rgb::new(
            u8::from_str_radix(&raw_color[0..2], 16)?,
            u8::from_str_radix(&raw_color[5..7], 16)?,
            u8::from_str_radix(&raw_color[10..12], 16)?,
        )),
        _ => Err(TlError::WrongFormat(s.to_string())),
    }
}
