#!/usr/bin/perl

=head1 NAME

dh_elpa - install emacs lisp packages into package build directories

=cut

use strict;
use Cwd qw{ getcwd };
use File::Temp qw{ tempdir tempfile};
use IO::Handle;

use Debian::Debhelper::Dh_Lib;

=head1 SYNOPSIS

B<dh_elpa> [S<I<debhelper options>>]  [S<I<pkg-file>>]

=head1 DESCRIPTION

B<dh_elpa> is a debhelper program that is responsible for installing
elpa style emacs lisp packages into package build directories.

=head1 FILES

=over 4

=item debian/I<package>.elpa

List of files to be installed into I<package> as an elpa package.

=back

=cut

init(options => {
	"byte-compile!" => \$dh{BYTECOMPILE},
});

=head1 OPTIONS

=over 4

=item B<--byte-compile>, B<--no-byte-compile>

Enable (default) or disable byte compilation of installed emacs lisp
files.  Disabling byte compilation changes the destination directory
to one that is found by the emacs package system.

=back

=cut

sub doit_quietly {
  my ($handle,$tmpfile) = tempfile(UNLINK=>1);
  my $exitcode;

  verbose_print(escape_shell(@_));
  open (CPERR,">&STDERR") or die "$!";
  open (CPOUT,">&STDOUT") or die "$!";
  STDOUT->fdopen($handle,'w');
  STDERR->fdopen($handle,'w');
  my $ret=doit_noerror(@_);
  STDOUT->fdopen(\*CPOUT,'w');
  STDERR->fdopen(\*CPERR,'w');

  if (!$ret){
    $exitcode=$?;
    seek $handle, 0, 0 or die "$!";
    print while (<$handle>);
    my $command=join(" ",@_);
    error("$command returned exit code ".($exitcode >> 8));
  }

}

my $templatedir = "/usr/share/debhelper/dh_elpa/emacsen-common";

sub maybe_install_helper{
  my ($package,$piece, $mode)=@_;
  my $file=pkgfile($package,"emacsen-$piece");

  my $tmp=tmpdir($package);
  my $ecdest="$tmp/usr/lib/emacsen-common/packages";

  # if there is file, leave it for dh_installemacsen
  if ($file eq '') {
    if (! -d "$ecdest/$piece") {
      doit("install","-d","$ecdest/$piece");
    }

    doit("install","-m$mode","$templatedir/$piece",
         "$ecdest/$piece/$package");
  }
}

$dh{BYTECOMPILE} = 1 unless defined($dh{BYTECOMPILE});

my $elpadir;

my $dhelpadir="/usr/share/emacs/site-lisp/elpa";

if ($dh{BYTECOMPILE}) {
  $elpadir="/usr/share/emacs/site-lisp/elpa-src";
} else {
  $elpadir=$dhelpadir;
}

foreach my $package (@{$dh{DOPACKAGES}}) {

  my $tmp=tmpdir($package);
  my $file=pkgfile($package,"elpa");

  if ($dh{BYTECOMPILE}) {
    maybe_install_helper($package,'compat','0644');
    maybe_install_helper($package,'install','0755');
    maybe_install_helper($package,'remove','0755');

    if (! $dh{NOSCRIPTS}) {
      autoscript($package,"postinst","postinst-emacsen",
                 "s/#PACKAGE#/$package/");
      autoscript($package,"prerm","prerm-emacsen",
                 "s/#PACKAGE#/$package/");
    }
  }

  my $elpapkg=$package;
  # TODO do this more sanely or at least allow an override
  $elpapkg =~ s/^elpa-//;
  verbose_print("Using elpa package name $elpapkg");

  my @files;

  # Call isnative because it sets $dh{VERSION}
  # as a side effect.
  isnative($package);
  if ($file) {
    @files=filearray($file, ".");
  }
  if (($package eq $dh{FIRSTPACKAGE} || $dh{PARAMS_ALL})
      && @ARGV) {
    push @files, @ARGV;
  }

  my $pkg_file;
  if (scalar(@files) == 1) {
    $pkg_file=$files[0];
  } else {
    my $tempdir = tempdir(CLEANUP => 1);
    my $version = $dh{VERSION} or die "version not found!";
    $version =~ s/-[^-]+//;  # strip Debian version
    my $pkg_dir = "$elpapkg-$version";

    $pkg_file = "$tempdir/$pkg_dir.tar";
    mkdir "$tempdir/$pkg_dir" or die "$!";

    # copy files into tempdir, flattening hierarchy
    # TODO: do this more correctly
    foreach my $el_file (@files) {
      doit("cp", "-a", $el_file, "$tempdir/$pkg_dir");
    }

    my $cwd = getcwd();
    chdir $tempdir or die "$!";
    doit("tar","cf",$pkg_file,$pkg_dir);
    chdir $cwd or die "$!";
  }

  doit_quietly(qw{emacs -batch -Q -l package},
               '--eval',"(add-to-list 'package-directory-list \"$dhelpadir\")",
               '--eval',"(add-to-list 'package-directory-list \"$elpadir\")",
       qw{-f package-initialize -l dh-elpa.el},
       qw{-f dhelpa-batch-install-file}, "$tmp/$elpadir", $pkg_file);
}

=head1 EXAMPLES

Here is an example of using the helper in a dh(1) style debian/rules

=over 4

override_dh_install:
        dh_install
        dh_elpa

=back

=cut

