//! Build progress tracking and reporting, for the purpose of display to the
//! user.

use crate::{
    graph::Build, graph::BuildId, process::Termination, task::TaskResult, terminal,
    work::BuildState, work::StateCounts,
};
use std::collections::VecDeque;
use std::io::Write;
use std::sync::Arc;
use std::sync::Condvar;
use std::sync::Mutex;
use std::time::Duration;
use std::time::Instant;

/// Compute the message to display on the console for a given build.
pub fn build_message(build: &Build) -> &str {
    build
        .desc
        .as_ref()
        .filter(|desc| !desc.is_empty())
        .unwrap_or_else(|| build.cmdline.as_ref().unwrap())
}

/// Trait for build progress notifications.
pub trait Progress {
    /// Called as individual build tasks progress through build states.
    fn update(&mut self, counts: &StateCounts);

    /// Called when a task starts.
    fn task_started(&mut self, id: BuildId, build: &Build);

    /// Called when a task's last line of output changes.
    fn task_output(&mut self, id: BuildId, line: Vec<u8>);

    /// Called when a task completes.
    fn task_finished(&mut self, id: BuildId, build: &Build, result: &TaskResult);

    /// Log a line of output without corrupting the progress display.
    /// This line is persisted beyond further progress updates.  For example,
    /// used when a task fails; we want the final output to show that failed
    /// task's output even if we do more work after it fails.
    fn log(&mut self, msg: &str);
}

/// Currently running build task, as tracked for progress updates.
struct Task {
    id: BuildId,
    /// When the task started running.
    start: Instant,
    /// Build status message for the task.
    message: String,
    /// Last line of output from the task.
    last_line: Option<String>,
}

/// Progress implementation for "dumb" console, without any overprinting.
#[derive(Default)]
pub struct DumbConsoleProgress {
    /// Whether to print command lines of started programs.
    verbose: bool,

    /// The id of the last command printed, used to avoid printing it twice
    /// when we have two updates from the same command in a row.
    last_started: Option<BuildId>,
}

impl DumbConsoleProgress {
    pub fn new(verbose: bool) -> Self {
        Self {
            verbose,
            last_started: None,
        }
    }
}

impl Progress for DumbConsoleProgress {
    fn update(&mut self, _counts: &StateCounts) {
        // ignore
    }

    fn task_started(&mut self, id: BuildId, build: &Build) {
        self.log(if self.verbose {
            build.cmdline.as_ref().unwrap()
        } else {
            build_message(build)
        });
        self.last_started = Some(id);
    }

    fn task_output(&mut self, _id: BuildId, _line: Vec<u8>) {
        // ignore
    }

    fn task_finished(&mut self, id: BuildId, build: &Build, result: &TaskResult) {
        match result.termination {
            Termination::Success => {
                if result.output.is_empty() || self.last_started == Some(id) {
                    // Output is empty, or we just printed the command, don't print it again.
                } else {
                    self.log(build_message(build))
                }
            }
            Termination::Interrupted => self.log(&format!("interrupted: {}", build_message(build))),
            Termination::Failure => self.log(&format!("failed: {}", build_message(build))),
        };
        if !result.output.is_empty() {
            std::io::stdout().write_all(&result.output).unwrap();
        }
    }

    fn log(&mut self, msg: &str) {
        println!("{}", msg);
    }
}

/// Progress implementation for "fancy" console, with progress bar etc.
/// Each time it prints, it clears from the cursor to the end of the console,
/// prints the status text, and then moves moves the cursor back up to the
/// start position.  This means on errors etc. we can clear any status by
/// clearing the console too.
pub struct FancyConsoleProgress {
    state: Arc<Mutex<FancyState>>,
}

/// Screen updates happen after this duration passes, to reduce the amount
/// of printing in the case of rapid updates.  This helps with terminal flicker.
const UPDATE_DELAY: Duration = std::time::Duration::from_millis(50);

impl FancyConsoleProgress {
    pub fn new(verbose: bool) -> Self {
        let dirty_cond = Arc::new(Condvar::new());
        let state = Arc::new(Mutex::new(FancyState {
            done: false,
            dirty: false,
            dirty_cond: dirty_cond.clone(),
            counts: StateCounts::default(),
            tasks: VecDeque::new(),
            verbose,
        }));

        // Thread to debounce status updates -- waits a bit, then prints after
        // any dirty state.
        std::thread::spawn({
            let state = state.clone();
            move || loop {
                // Wait to be notified of a display update, or timeout at 500ms.
                // The timeout is for the case where there are lengthy build
                // steps and the progress will show how long they've been
                // running.
                {
                    let (state, _) = dirty_cond
                        .wait_timeout_while(
                            state.lock().unwrap(),
                            Duration::from_millis(500),
                            |state| !state.dirty,
                        )
                        .unwrap();
                    if state.done {
                        break;
                    }
                }

                // Delay a little bit in case more display updates come in.
                std::thread::sleep(UPDATE_DELAY);

                // Update regardless of whether we timed out or not.
                state.lock().unwrap().print_progress();
            }
        });

        FancyConsoleProgress { state }
    }
}

impl Progress for FancyConsoleProgress {
    fn update(&mut self, counts: &StateCounts) {
        self.state.lock().unwrap().update(counts);
    }

    fn task_started(&mut self, id: BuildId, build: &Build) {
        self.state.lock().unwrap().task_started(id, build);
    }

    fn task_output(&mut self, id: BuildId, line: Vec<u8>) {
        self.state.lock().unwrap().task_output(id, line);
    }

    fn task_finished(&mut self, id: BuildId, build: &Build, result: &TaskResult) {
        self.state.lock().unwrap().task_finished(id, build, result);
    }

    fn log(&mut self, msg: &str) {
        self.state.lock().unwrap().log(msg);
    }
}

impl Drop for FancyConsoleProgress {
    fn drop(&mut self) {
        self.state.lock().unwrap().cleanup();
    }
}

struct FancyState {
    done: bool,
    dirty: bool,
    dirty_cond: Arc<Condvar>,

    /// Counts of tasks in each state.  TODO: pass this as function args?
    counts: StateCounts,
    /// Build tasks that are currently executing.
    /// Pushed to as tasks are started, so it's always in order of age.
    tasks: VecDeque<Task>,
    /// Whether to print command lines of started programs.
    verbose: bool,
}

impl FancyState {
    fn dirty(&mut self) {
        self.dirty = true;
        self.dirty_cond.notify_one();
    }

    fn update(&mut self, counts: &StateCounts) {
        self.counts = counts.clone();
        self.dirty();
    }

    fn task_started(&mut self, id: BuildId, build: &Build) {
        if self.verbose {
            self.log(build.cmdline.as_ref().unwrap());
        }
        let message = build_message(build);
        self.tasks.push_back(Task {
            id,
            start: Instant::now(),
            message: message.to_string(),
            last_line: None,
        });
        self.dirty();
    }

    fn task_output(&mut self, id: BuildId, line: Vec<u8>) {
        let task = self.tasks.iter_mut().find(|t| t.id == id).unwrap();
        task.last_line = Some(String::from_utf8_lossy(&line).into_owned());
        self.dirty();
    }

    fn task_finished(&mut self, id: BuildId, build: &Build, result: &TaskResult) {
        self.tasks
            .remove(self.tasks.iter().position(|t| t.id == id).unwrap());
        match result.termination {
            Termination::Success => {
                if result.output.is_empty() {
                    // Common case: don't show anything.
                } else {
                    self.log(build_message(build))
                }
            }
            Termination::Interrupted => self.log(&format!("interrupted: {}", build_message(build))),
            Termination::Failure => self.log(&format!("failed: {}", build_message(build))),
        };
        if !result.output.is_empty() {
            std::io::stdout().write_all(&result.output).unwrap();
        }
        self.dirty();
    }

    fn log(&mut self, msg: &str) {
        self.clear_progress();
        println!("{}", msg);
        self.dirty();
    }

    fn cleanup(&mut self) {
        self.clear_progress();
        self.done = true;
        self.dirty(); // let thread quit
    }

    fn clear_progress(&self) {
        // If the user hit ctl-c, it may have printed something on the line.
        // So \r to go to first column first, then clear anything below.
        std::io::stdout().write_all(b"\r\x1b[J").unwrap();
    }

    fn print_progress(&mut self) {
        self.clear_progress();
        let failed = self.counts.get(BuildState::Failed);
        let mut progress_line = format!(
            "[{}] {}/{} done, ",
            progress_bar(&self.counts, 40),
            self.counts.get(BuildState::Done) + failed,
            self.counts.total()
        );
        if failed > 0 {
            progress_line.push_str(&format!("{} failed, ", failed));
        }
        progress_line.push_str(&format!(
            "{}/{} running",
            self.tasks.len(),
            self.counts.get(BuildState::Queued)
                + self.counts.get(BuildState::Running)
                + self.counts.get(BuildState::Ready),
        ));
        println!("{}", progress_line);
        let mut lines = 1;

        let max_cols = terminal::get_cols().unwrap_or(80);
        let max_tasks = 8;
        let now = Instant::now();
        for task in self.tasks.iter().take(max_tasks) {
            let delta = now.duration_since(task.start).as_secs() as usize;
            println!("{}", task_message(&task.message, delta, max_cols));
            lines += 1;
            if let Some(line) = &task.last_line {
                let max_len = max_cols - 2;
                println!("  {}", truncate(line, max_len));
                lines += 1;
            }
        }

        if self.tasks.len() > max_tasks {
            let remaining = self.tasks.len() - max_tasks;
            println!("...and {} more", remaining);
            lines += 1;
        }

        // Move cursor up to the first printed line, for overprinting.
        print!("\x1b[{}A", lines);
        self.dirty = false;
    }
}

/// Format a task's status message to optionally include how long it has been running
/// and also to fit within a maximum number of terminal columns.
fn task_message(message: &str, seconds: usize, max_cols: usize) -> String {
    let time_note = if seconds > 2 {
        format!(" ({}s)", seconds)
    } else {
        "".into()
    };
    let mut out = message.to_owned();
    if out.len() + time_note.len() >= max_cols {
        out.truncate(max_cols - time_note.len() - 3);
        out.push_str("...");
    }
    out.push_str(&time_note);
    out
}

fn truncate(s: &str, mut max: usize) -> &str {
    if max >= s.len() {
        return s;
    }
    while !s.is_char_boundary(max) {
        max -= 1;
    }
    &s[..max]
}

/// Render a StateCounts as an ASCII progress bar.
fn progress_bar(counts: &StateCounts, bar_size: usize) -> String {
    let mut bar = String::with_capacity(bar_size);
    let mut sum: usize = 0;
    let total = counts.total();
    if total == 0 {
        return " ".repeat(bar_size);
    }
    for (count, ch) in [
        (
            counts.get(BuildState::Done) + counts.get(BuildState::Failed),
            '=',
        ),
        (
            counts.get(BuildState::Queued)
                + counts.get(BuildState::Running)
                + counts.get(BuildState::Ready),
            '-',
        ),
        (counts.get(BuildState::Want), ' '),
    ] {
        sum += count;
        let mut target_size = sum * bar_size / total;
        if count > 0 && target_size == bar.len() && target_size < bar_size {
            // Special case: for non-zero count, ensure we always get at least
            // one tick.
            target_size += 1;
        }
        while bar.len() < target_size {
            bar.push(ch);
        }
    }
    bar
}

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

    #[test]
    fn progress_bar_rendering() {
        let mut counts = StateCounts::default();

        // Don't crash if we show progress before having any tasks.
        assert_eq!(progress_bar(&counts, 10), "          ");

        counts.add(BuildState::Want, 100);
        assert_eq!(progress_bar(&counts, 10), "          ");

        // Half want -> ready.
        counts.add(BuildState::Want, -50);
        counts.add(BuildState::Ready, 50);
        assert_eq!(progress_bar(&counts, 10), "-----     ");

        // One ready -> done.
        counts.add(BuildState::Ready, -1);
        counts.add(BuildState::Done, 1);
        assert_eq!(progress_bar(&counts, 10), "=----     ");

        // All but one want -> ready.
        counts.add(BuildState::Want, -49);
        counts.add(BuildState::Ready, 49);
        assert_eq!(progress_bar(&counts, 10), "=-------- ");

        // All want -> ready.
        counts.add(BuildState::Want, -1);
        counts.add(BuildState::Ready, 1);
        assert_eq!(progress_bar(&counts, 10), "=---------");
    }

    #[test]
    fn task_rendering() {
        assert_eq!(task_message("building foo.o", 0, 80), "building foo.o");
        assert_eq!(task_message("building foo.o", 0, 10), "buildin...");
        assert_eq!(task_message("building foo.o", 0, 5), "bu...");
    }

    #[test]
    fn task_rendering_with_time() {
        assert_eq!(task_message("building foo.o", 5, 80), "building foo.o (5s)");
        assert_eq!(task_message("building foo.o", 5, 10), "bu... (5s)");
    }

    #[test]
    fn truncate_utf8() {
        let text = "utf8 progress bar: ━━━━━━━━━━━━";
        for len in 10..text.len() {
            // test passes if this doesn't panic
            truncate(text, len);
        }
    }
}
