#!/usr/bin/perl

# Copyright © 2022 Felix Lechner <felix.lechner@lease-up.com>
#
# based on a shell script by the same name
#     Joachim Breitner <nomeata@debian.org>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

use v5.20;
use warnings;
use utf8;

use Const::Fast;
use File::Basename;
use Getopt::Long ();
use Path::Tiny;
use Unicode::UTF8 qw(encode_utf8);

use Debian::Debhelper::Buildsystem::Haskell::Recipes qw(
  run
  package_ext
  packages_hc
);

const my $EMPTY => q{};
const my $SPACE => q{ };
const my $NEWLINE => qq{\n};

my $program_name = basename($0);

my @excludes;

my %options = (
    'exclude|X=s' => \@excludes,
    'help|h' => \&show_help,
);

Getopt::Long::Configure('gnu_getopt', 'pass_through');
Getopt::Long::GetOptions(%options)
  or die encode_utf8("error parsing options\n");

my @args_bytes = grep { /^-/ } @ARGV;
my ($default_compiler, @configs) = grep { !/^-/ } @ARGV;

die encode_utf8("Installed package description file $_ can not be found")
  for grep { !-e } @configs;

$ENV{DH_EXCLUDES} = join($SPACE, @excludes);

die encode_utf8('grep-dctrl is missing')
  unless system('command -v grep-dctrl > /dev/null') == 0;

$ENV{DEB_DEFAULT_COMPILER} = $default_compiler;
my $compiler = packages_hc();

my $output = run('dh_listpackages', @args_bytes);
chomp $output;

my @installables = split($SPACE, $output);

for my $installable (@installables) {

    my $substvars_path = "debian/$installable.substvars";

    my $short_blurb;
    my $blurb;

    my $extension = package_ext($installable);
    if ($extension eq 'dev') {

        $short_blurb = $EMPTY;
        $blurb
          = 'This package provides a library for the Haskell programming language.${Newline}See http://www.haskell.org/ for more information on Haskell.';

    }

    if ($extension eq 'prof') {

        $short_blurb = '; profiling libraries';
        $blurb
          = 'This package provides a library for the Haskell programming language, compiled${Newline}for profiling.  See http://www.haskell.org/ for more information on Haskell.';

    }

    if ($extension eq 'doc') {

        $short_blurb = '; documentation';
        $blurb
          = 'This package provides the documentation for a library for the Haskell${Newline}programming language.${Newline}See http://www.haskell.org/ for more information on Haskell.';

    }

    replace_line($substvars_path, 'haskell:ShortBlurb',$short_blurb // $EMPTY);
    replace_line($substvars_path, 'haskell:Blurb', $blurb // $EMPTY);

    # need regex to avoid the empty string, which would be filtered by run()
    my $description
      = run(
        qw{grep-dctrl --no-field-names --show-field=X-Description --field=Source --regex .* debian/control}
      );
    my ($short_description, $long_description) = split(m{\n}, $description, 2);

    $short_description //= $EMPTY;
    $long_description //= $EMPTY;

    chomp $long_description;

    # drop initial spaces
    $long_description =~ s{^ [ ] }{}gmx;

    # prepare for dpkg-gencontrol
    $long_description =~ s{ \n }{\$\{Newline\}}gx;

    replace_line($substvars_path, 'haskell:ShortDescription',
        $short_description);
    replace_line($substvars_path, 'haskell:LongDescription',$long_description);

    my $version= run(qw{dpkg-query --showformat=${Version} --show}, $compiler);
    chomp $version;

    # drop Debian revision
    $version =~ s{ - [^-]+ $}{}x;

    replace_line($substvars_path, "haskell:$compiler-version",
        "$compiler (>= $version), $compiler (<< $version+)");
}

exit;

sub replace_line {
    my ($path, $field, $value) = @_;

    $value //= $EMPTY;

    path($path)->touch;

    my @lines = grep { !m{^ $field = }x } path($path)->lines_utf8;

    push(@lines, "$field=$value" . $NEWLINE);

    path($path)->spew_utf8(@lines);

    return;
}

sub show_help {
    my $message =<<"EOT";
Usage: $program_name [options] cabal-file ...

Options:
    -X, --exclude INSTALLABLE    exclude INSTALLABLE from processing
EOT

    print encode_utf8($message);

    exit;
}

=head1 NAME

dh_haskell_blurb - standard haskell package description blurbs

=head1 SYNOPSIS

B<dh_haskell_blurbs> [S<I<debhelper options>>]
[B<-X>I<package>]
[B<--exclude=>I<package>]
[S<I<file>> ...]

=head1 DESCRIPTION

dh_haskell_blurbs is a debhelper program provides substvars for the standard blurbs occurring in Haskell package descriptions.

To use it, move the common parts of the description to the source stanza:

 X-Description: Cool library
  This is a pure Haskell implementation of coolness. It is cooler
  than implementation via foreign languages, because we can.

And then use the following for every Haskell library package stanza, C<dev>, C<prof> and C<doc>:

 Description: ${haskell:ShortDescription}${haskell:ShortBlurb}
  ${haskell:LongDescription}
  .
  ${haskell:Blurb}


=head1 SEE ALSO

L<dh_haskell_depends(1)>
L<dh_haskell_shlibdeps(1)>
L<dh_haskell_provides(1)>
L<debhelper(7)>

=head1 AUTHOR

Joachim Breitner <nomeata@debian.org>

=cut

# Local Variables:
# indent-tabs-mode: nil
# cperl-indent-level: 4
# End:
# vim: syntax=perl sw=4 sts=4 sr et
