/*
 * libgit2 "blame" example - shows how to use the blame API
 *
 * Written by the libgit2 contributors
 *
 * To the extent possible under law, the author(s) have dedicated all copyright
 * and related and neighboring rights to this software to the public domain
 * worldwide. This software is distributed without any warranty.
 *
 * You should have received a copy of the CC0 Public Domain Dedication along
 * with this software. If not, see
 * <http://creativecommons.org/publicdomain/zero/1.0/>.
 */

#![deny(warnings)]

use git2::{BlameOptions, Repository};
use std::io::{BufRead, BufReader};
use std::path::Path;
use structopt::StructOpt;

#[derive(StructOpt)]
#[allow(non_snake_case)]
struct Args {
    #[structopt(name = "path")]
    arg_path: String,
    #[structopt(name = "spec")]
    arg_spec: Option<String>,
    #[structopt(short = "M")]
    /// find line moves within and across files
    flag_M: bool,
    #[structopt(short = "C")]
    /// find line copies within and across files
    flag_C: bool,
    #[structopt(short = "F")]
    /// follow only the first parent commits
    flag_F: bool,
}

fn run(args: &Args) -> Result<(), git2::Error> {
    let repo = Repository::open(".")?;
    let path = Path::new(&args.arg_path[..]);

    // Prepare our blame options
    let mut opts = BlameOptions::new();
    opts.track_copies_same_commit_moves(args.flag_M)
        .track_copies_same_commit_copies(args.flag_C)
        .first_parent(args.flag_F);

    let mut commit_id = "HEAD".to_string();

    // Parse spec
    if let Some(spec) = args.arg_spec.as_ref() {
        let revspec = repo.revparse(spec)?;

        let (oldest, newest) = if revspec.mode().contains(git2::RevparseMode::SINGLE) {
            (None, revspec.from())
        } else if revspec.mode().contains(git2::RevparseMode::RANGE) {
            (revspec.from(), revspec.to())
        } else {
            (None, None)
        };

        if let Some(commit) = oldest {
            opts.oldest_commit(commit.id());
        }

        if let Some(commit) = newest {
            opts.newest_commit(commit.id());
            if !commit.id().is_zero() {
                commit_id = format!("{}", commit.id())
            }
        }
    }

    let spec = format!("{}:{}", commit_id, path.display());
    let blame = repo.blame_file(path, Some(&mut opts))?;
    let object = repo.revparse_single(&spec[..])?;
    let blob = repo.find_blob(object.id())?;
    let reader = BufReader::new(blob.content());

    for (i, line) in reader.lines().enumerate() {
        if let (Ok(line), Some(hunk)) = (line, blame.get_line(i + 1)) {
            let sig = hunk.final_signature();
            println!(
                "{} {} <{}> {}",
                hunk.final_commit_id(),
                String::from_utf8_lossy(sig.name_bytes()),
                String::from_utf8_lossy(sig.email_bytes()),
                line
            );
        }
    }

    Ok(())
}

fn main() {
    let args = Args::from_args();
    match run(&args) {
        Ok(()) => {}
        Err(e) => println!("error: {}", e),
    }
}
