An implementation of git fast-export for Pijul
use clap::Parser;

mod repo;
use repo::Repository;

mod fast_export;
use fast_export::FastExportStream;

mod changestore;

#[derive(Parser)]
struct Cli {
    #[arg(long, default_value = ".", help = "repository path")]
    repo: String,

    #[arg(long, default_value = "main", help = "channel to export")]
    channel: String,

    #[arg(long, help = "branch name in git")]
    branch: Option<String>,

    #[arg(long, help = "file to import and export marks")]
    marks: Option<String>,

    #[arg(
        long = "progress-interval",
        help = "report progress every N commits",
        value_name = "N"
    )]
    progress_interval: Option<i32>,
}

fn main() {
    let cli = Cli::parse();

    let mut repo = Repository::load(&cli.repo).unwrap();
    let mut stream = FastExportStream::new(cli.branch.unwrap_or(cli.channel.to_string()));

    match cli.marks {
        Some(ref filename) => stream.load_marks(filename).unwrap(),
        None => (),
    }

    let changes = repo.log(&cli.channel).unwrap();
    let mut sandbox = repo.new_sandbox().unwrap();
    let mut count = 0;

    for i in 0..changes.len() {
        sandbox.add_change(&changes[i]).unwrap();
        if !stream.already_exported(&changes[i].state) {
            let files = sandbox.get_files(changes[i].hash).unwrap();
            let parent = if i == 0 {
                None
            } else {
                Some(changes[i - 1].state)
            };
            stream.write_commit(&changes[i], parent, &files);
        }
        count += 1;
        if let Some(p) = cli.progress_interval {
            if count % p == 0 {
                println!(
                    "progress Exported {} changes; current change is {:?}",
                    count, changes[i].hash
                );
            }
        }
    }

    match cli.marks {
        Some(ref filename) => stream.save_marks(filename).unwrap(),
        None => (),
    }
}