#!/usr/bin/env perl
#
# This program creates a source distribution of qpdf.  For details,
# see README-maintainer.md.
#

require 5.008;
use warnings;
use strict;
use File::Basename;
use Cwd;
use Cwd 'abs_path';
use IO::File;
use File::Path qw(rmtree);

my $whoami = basename($0);

my $run_tests = 1;
my $keep_tmp = 0;
my $ci_mode = 0;
my $version = undef;
foreach my $arg (@ARGV)
{
    if ($arg eq '--no-tests')
    {
	$run_tests = 0;
    }
    elsif ($arg eq '--keep-tmp')
    {
        $keep_tmp = 1;
    }
    elsif ($arg eq '--ci')
    {
        $ci_mode = 1;
    }
    elsif (! defined $version)
    {
        $version = $arg;
    }
    else
    {
	usage();
    }
}

if ($ci_mode && (! defined $version))
{
    $version = get_version_from_configure();
}

usage() unless defined $version;
usage() unless $version =~ m/^(\d+\.\d+(?:\.(a|b|rc)?\d+)?)$/;
my $distname = "qpdf-$version";
my $tmpdir = "/tmp/$distname";
if ((-d $tmpdir) && (! $keep_tmp))
{
    rmtree($tmpdir);
}
run("git archive --prefix=qpdf-$version/ HEAD . | (cd /tmp; tar xf -)");
cd($tmpdir);

# Check versions
my $config_version = get_version_from_configure();
my $code_version = get_version_from_source();
my $doc_version = get_version_from_manual();
my $cli_version = get_version_from_cli();

my $version_error = 0;
if ($version ne $config_version)
{
    print "$whoami: configure.ac version = $config_version\n";
    $version_error = 1;
}
if ($version ne $code_version)
{
    print "$whoami: QPDF.cc version = $code_version\n";
    $version_error = 1;
}
if ($version ne $doc_version)
{
    print "$whoami: qpdf-manual.xml version = $doc_version\n";
    $version_error = 1;
}
if ($version ne $cli_version)
{
    print "$whoami: qpdf.cc version = $cli_version\n";
    $version_error = 1;
}
if ($version_error)
{
    die "$whoami: version numbers are not consistent\n";
}

run("./configure --disable-shared --enable-doc-maintenance --enable-werror");
run("make -j8 build_manual");
run("make distclean");
cd("/tmp");
run("tar czvf $distname.tar.gz-candidate $distname");
if ($run_tests)
{
    cd($tmpdir);
    run("./configure");
    run("make -j8");
    run("make check");
    cd("/tmp");
}
my $distfile = ($ci_mode ? "$distname-ci.tar.gz" : "$distname.tar.gz");
rename "$distname.tar.gz-candidate", $distfile or die;

if (! $keep_tmp)
{
    rmtree($tmpdir);
}

print "
Source distribution created as /tmp/$distfile
If this is a release, don't forget to tag the version control system and
make a backup of the release tar file.

";

sub get_version_from_configure
{
    my $fh = safe_open("configure.ac");
    my $config_version = 'unknown';
    while (<$fh>)
    {
        if (m/^AC_INIT\(\[qpdf\],\[([^\)]+)\]\)/)
        {
            $config_version = $1;
            last;
        }
    }
    $fh->close();
    $config_version;
}

sub get_version_from_source
{
    my $fh = safe_open("libqpdf/QPDF.cc");
    my $code_version = 'unknown';
    while (<$fh>)
    {
        if (m/QPDF::qpdf_version = \"([^\"]+)\"/)
        {
            $code_version = $1;
            last;
        }
    }
    $fh->close();
    $code_version;
}

sub get_version_from_manual
{
    my $fh = safe_open("manual/qpdf-manual.xml");
    my $doc_version = 'unknown';
    while (<$fh>)
    {
        if (m/swversion "([^\"]+)\"/)
        {
            $doc_version = $1;
            last;
        }
    }
    $fh->close();
    $doc_version;
}

sub get_version_from_cli
{
    my $fh = safe_open("qpdf/qpdf.cc");
    my $cli_version = 'unknown';
    while (<$fh>)
    {
        if (m/expected_version = \"([^\"]+)\"/)
        {
            $cli_version = $1;
            last;
        }
    }
    $fh->close();
    $cli_version;
}

sub safe_open
{
    my $file = shift;
    my $fh = new IO::File("<$file") or die "$whoami: can't open $file: $!";
    $fh;
}

sub run
{
    my $cmd = shift;
    system($cmd) == 0 or die "$whoami: $cmd failed\n";
}

sub cd
{
    my $dir = shift;
    chdir($dir) or die;
}

sub usage
{
    die "
Usage: $whoami [ --no-tests --keep-tmp ] version

Use of --no-tests can be used for internally testing releases, but do
not use it for a real release.

$whoami creates /tmp/qpdf-<version> and deletes it when done. With
--keep-tmp, the directory is kept. This can be useful for debugging
the release process.

";
}