#! /usr/bin/perl
use warnings;
use strict;
use integer;
use FindBin;
use lib $FindBin::RealBin;
use Def;

# Before running this script, you should add a changelog entry (even an
# empty one) for the current version, if you've not yet done so.  The
# script modifies whichever entry happens to be at the changelog's top.
#
# This helper script automatically updates the package's issue date in
# several files (the files are named in the following block).  The
# script accepts date and time in any format the date(1) command
# understands, but it writes the date (and time) to each file in that
# file's appropriate format.  Example usage:
#
#   $ update-date '24 Jan 2005 21:00 +0000'
#
# If no time of day is given, it defaults to 00:00:00 +0000.
#
# When also running the helper/update-ver script, you probably want to
# run that script first, then this one.  Otherwise debian/changelog is
# updated in a different manner than you probably thought to update it.
#
# Note that the script does not change the name of the top-level source
# directory.  This is for sanity's sake.  You must change the name of
# the directory yourself.
#
# Note also that the self entry in bib.bib, where the book refers to
# itself, must appear first to run this script.  If something else
# appears first, the script may happily try to update that date,
# instead.

our $debian        = "${FindBin::RealBin}/../../debian"               ;
our $maintex       = "${FindBin::RealBin}/../../tex/${Def::main0}.tex";
our $mainbib       = "${FindBin::RealBin}/../../tex/${Def::bib0}.bib" ;
our $manpage       =
  "${FindBin::RealBin}/../../doc/${Def::out}.${Def::mansect}"         ;
our $readme        = "${FindBin::RealBin}/../../${Def::name_readme}"  ;
our $changelog     = "${FindBin::RealBin}/../../doc/changelog"        ;
our $changelog_deb = "${debian}/changelog"                            ;
our $copyright     = "${debian}/copyright"                            ;

my $warn_msg = "$0: cannot find date line in ";

our $usage = <<END;
usage: $0 [-dcsh] date-time
    -d update only the Debian-specific files
    -c update only the Debian-specific files and doc/changelog
    -s update only changelog signature dates
    -h print this usage message
END

# Read command-line arguments and options.
my @arg;
my %opt;
for ( @ARGV ) {
  if ( my($o) = /^-(\S+)/ ) {
    $opt{$_} = 1 for split //, $o;
  }
  else { push @arg, $_ }
}
if ( $opt{h} || $opt{'?'} ) {
  print $usage;
  exit 0;
}

# Determine which parts of the source to update in.
my $do_main = !$opt{d} && !$opt{c} && !$opt{s};
my $do_cl   = !$opt{d} ||  $opt{c};
my $do_deb  = -e $debian;

# Prepare date strings.
my $ind;
@arg == 1 && (
  $ind = $arg[0] =~ /:/
  ? `date -ud'$arg[0]'` : `date -ud'$arg[0] 00:00:00 +0000'`,
  !$?
) or die "usage: $0 date\n";
my $date = `date -ud'$ind' +'%e %B %Y'`; $date =~ s/^\s*//; chomp $date;
my $year = `date -ud'$ind' +'%Y'`      ; $year =~ s/^\s*//; chomp $year;
my $verd = `date -ud'$ind' +'%Y%m%d'`  ; $verd =~ s/^\s*//; chomp $verd;
my $cld  = `date -ud'$ind' -R`         ; $cld  =~ s/^\s*//; chomp $cld ;

# Read files in.
my( @main, @bib, @man, @cl, @rme, @cr, @cld );
if ( $do_main ) {
  open MAIN, '<', $maintex      ;
  open BIB , '<', $mainbib      ;
  open MAN , '<', $manpage      ;
  open RME , '<', $readme       ;
  open CR  , '<', $copyright    ;
  @main = <MAIN>;
  @bib  = <BIB> ;
  @man  = <MAN> ;
  @rme  = <RME> ;
  @cr   = <CR>  ;
  close MAIN;
  close BIB ;
  close MAN ;
  close RME ;
  close CR  ;
}
if ( $do_cl   ) {
  open CL  , '<', $changelog    ;
  @cl   = <CL>  ;
  close CL  ;
}
if ( $do_deb  ) {
  open CLD , '<', $changelog_deb;
  @cld  = <CLD> ;
  close CLD ;
}

if ( $do_main ) {

  # Update the dates in the main TeX source file.
  $_ = 0; ++$_ until $_ > $#main ||
    $main[$_] =~
      s/^(\\newcommand\{\\veryear\}\{)([^\{\}]+)(\})\s*?$/$1$year$3/;
    $_ <= $#main or warn "$warn_msg$maintex\n";
  $_ = 0; ++$_ until $_ > $#main ||
    $main[$_] =~
      s/^(\\newcommand\{\\verdate\}\{)([^\{\}]+)(\})\s*?$/$1$date$3/;
    $_ <= $#main or warn "$warn_msg$maintex\n";

  # Update the date in the bibliography's (leading) self-entry.
  $_ = 0; ++$_ until $_ > $#bib ||
    $bib[$_] =~ s/^(\s*year=\{)([^\{\}]+)(\},)\s*?$/$1$date$3/;
    $_ <= $#bib or warn "$warn_msg$mainbib\n";

  # Update the dates on the manpage.
  $man[0] =~ s/(")([^"]*?)("\s*\\)$/$1$date$3/
    or warn "$warn_msg$manpage\n";
  $_ = $#man; --$_ until $_ < 0 ||
    $man[$_] =~ s/^(Copyright \(C\) \d+\\-)(\d+)/$1$year/;
    $_ >= 0 or warn "$warn_msg$manpage\n";

  # Update the date at the foot of the readme and the copyright year
  # therein.
  $_ = $#rme; --$_ until $_ < $#rme-1 ||
    # $rme[$_] =~ s/^(.*, )([^,\n]*,[^,\n]*)$/$1$cld/;
    $rme[$_] =~ s/^.*\S.*$/$cld/;
    $_ >= $#rme-1 or warn "$warn_msg$readme\n";
  --$_; --$_ until $_ < 0 ||
    $rme[$_] =~ s/^(Copyright \(C\) \d+-)(\d+)/$1$year/;
    $_ >= 0 or warn "$warn_msg$readme\n";

  # Update the year in the copyright file.
  $_ = 0; ++$_ until $_ > $#cr ||
    $cr[$_] =~ s/^(Copyright \(C\) \d+-)(\d+)/$1$year/;
    $_ <= $#cr or warn "$warn_msg$copyright\n";

}

if ( $do_cl ) {

  # Update the dates in the main changelog.
  unless ( $opt{s} ) {
    $cl[0] =~ s/(\([^()]*\.)(\d+)([^().]*?\))/$1$verd$3/
      or warn "$warn_msg$changelog\n";
  }
  {
    my $authe = "${Def::author} <${Def::email}>";
    $_ = 0; ++$_ until $_ > $#cl ||
      $cl[$_] =~ s/^( -- $authe  )(\S(?:.*?\S)??)\s*$/$1$cld\n/;
      $_ <= $#cl or warn "$warn_msg$changelog\n";
  }

}

if ( $do_deb ) {

  # Update the dates in the debian/changelog.
  unless ( $opt{s} ) {
    # Update the version date atop debian/changelog.
    $cld[0] =~ s/(\([^()]*\.)(\d+)([^().]*?\))/$1$verd$3/
      or warn "$warn_msg$changelog_deb\n";
  }
  {
    my $authe = "${Def::author} <${Def::email_deb}>";
    $_ = 0; ++$_ until $_ > $#cld ||
      $cld[$_] =~ s/^( -- $authe  )(\S(?:.*?\S)??)\s*$/$1$cld\n/;
      $_ <= $#cld or warn "$warn_msg$changelog_deb\n";
  }

}

# Write updated files out.
if ( $do_main ) {
  open MAIN, '>', $maintex      ;
  open BIB , '>', $mainbib      ;
  open MAN , '>', $manpage      ;
  open RME , '>', $readme       ;
  open CR  , '>', $copyright    ;
  print MAIN @main;
  print BIB  @bib ;
  print MAN  @man ;
  print RME  @rme ;
  print CR   @cr  ;
  close MAIN;
  close BIB ;
  close MAN ;
  close RME ;
  close CR  ;
}
if ( $do_cl   ) {
  open CL  , '>', $changelog    ;
  print CL   @cl  ;
  close CL  ;
}
if ( $do_deb  ) {
  open CLD , '>', $changelog_deb;
  print CLD  @cld ;
  close CLD ;
}

