// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use clap::Command;
use mdbook::MDBook;
use mdbook_course::course::Courses;
use mdbook_course::markdown::duration;

fn main() {
    pretty_env_logger::init();
    let app = Command::new("mdbook-course")
        .about("mdbook preprocessor for Comprehensive Rust")
        .subcommand(Command::new("sessions").about("Show session summary (default)"))
        .subcommand(Command::new("segments").about("Show segment summary"))
        .subcommand(Command::new("pr").about("Show summary for a PR"));
    let matches = app.get_matches();

    let root_dir = ".";
    let mdbook = MDBook::load(root_dir).expect("Unable to load the book");
    let (courses, _) = Courses::extract_structure(mdbook.book)
        .expect("Unable to extract course structure");

    match matches.subcommand() {
        Some(("session", _)) | None => session_summary(&courses),
        Some(("pr", _)) => pr_summary(&courses),
        _ => unreachable!(),
    }
}

fn timediff(actual: u64, target: u64, slop: u64) -> String {
    if actual > target + slop {
        format!(
            "{} (\u{23f0} *{} too long*)",
            duration(actual),
            duration(actual - target),
        )
    } else if actual + slop < target {
        format!("{}: ({} short)", duration(actual), duration(target - actual),)
    } else {
        format!("{}", duration(actual))
    }
}

fn session_summary(courses: &Courses) {
    for course in courses {
        if course.target_minutes() == 0 {
            return;
        }
        for session in course {
            println!("### {} // {}", course.name, session.name);
            println!(
                "_{}_",
                timediff(session.minutes(), session.target_minutes(), 15)
            );
            println!();
            for segment in session {
                println!("* {} - _{}_", segment.name, duration(segment.minutes()));
            }
            println!();
        }
    }
}

fn pr_summary(courses: &Courses) {
    println!("## Course Schedule");
    println!("With this pull request applied, the course schedule is as follows:");
    for course in courses {
        if course.target_minutes() == 0 {
            return;
        }
        println!("### {}", course.name);
        println!("_{}_", timediff(course.minutes(), course.target_minutes(), 15));

        for session in course {
            println!(
                "* {} - _{}_",
                session.name,
                timediff(session.minutes(), session.target_minutes(), 5)
            );
        }
    }
}
