#!/usr/bin/env perl
#======================================================================
# pre-commit hook for LaTeXML development
# do
#    ln -s ../../tools/pre-commit .git/hooks
#======================================================================
use warnings;
use strict;
use File::Spec::Functions qw(catfile splitpath splitdir);
use File::Temp qw(tempdir);
use ExtUtils::Manifest qw(fullcheck);
use Term::ANSIColor;

my $changes = `git status --porcelain`;
if (my @modified_files =
  map { $_->[1] }    # select the filename
  grep { $_->[0] =~ /^[AM]/ } # take only Modified or Added (with possible additional unstaged changes)
  map { [split(/\s+/, $_)] }  # [status, name]
  split("\n", $changes)) {    # from all files
  my @failed_files = ();
  my $exit_code    = 0;
  my $workdir      = tempdir("latexmllintXXXXXX", CLEANUP => 1, TMPDIR => 1);
  # Run latexmllint on each STAGED file
  foreach my $modified_file (@modified_files) {
    # First,
    #  Create a portion of the repo tree in the temporary working directory
    my ($volume, $directories, $file) = splitpath($modified_file);
    my @dirs = splitdir($directories);
    my $wd   = $workdir;
    foreach my $dir (@dirs) {
      $wd = catfile($wd, $dir);
      mkdir $wd unless -d $wd; }
    # Now create the file with the STAGED content in the temporary space.
    my $temp_file = catfile($workdir, $modified_file);
    system("git show ':$modified_file' > $temp_file");
    # Finally run latexmllint on it.
    my $status = system(catfile('tools', 'latexmllint'), "--precommit", $temp_file);
    my $code   = $status >> 8;
    if ($code) {
      push(@failed_files, $modified_file);    # Note the original file name
      $exit_code = $code; } }
  if (@failed_files) {
    print STDERR "Some files had issues: " . join(',', @failed_files)
      . "; To correct these, run:\n tools/latexmllint <files>.\n"; }

  # Also, Check if files are missing from the manifest
  my ($manifest_missing, $manifest_extra) = fullcheck();
  # Not in MANIFEST, (or in tools)
  my %manifest_missing = map  { $_ => 1 } @$manifest_missing;
  my @missing_files    = grep { $manifest_missing{$_} } @modified_files;
  if (@missing_files) {
    print STDERR "Some files are missing from MANIFEST, please add them: \n\t"
      . join(',\n\t', @missing_files) . ";\n";
    $exit_code = 1; }

  if (@missing_files || @failed_files) {
    print STDERR colored("COMMIT ABORTED", 'red') . "\n"; }
  exit $exit_code; }
