#!/usr/bin/perl
# Copyright (C) 2011-2013 Zentyal S.L.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License, version 2, as
# published by the Free Software Foundation.
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

use warnings;
use strict;
use Error qw(:try);
use File::Basename;
use Cwd qw(getcwd realpath);

my $REPO = getcwd;

my $DEST;
if (not $ENV{DESTINATION_DIR}) {
    $DEST =  "$REPO/debs-ppa";
} else {
    my $dest = $ENV{DESTINATION_DIR};
    if ($dest =~ m{^/}) {
        $DEST = $dest;
    } else {
        $DEST = "$REPO/" . $dest;
    }

    print "package files will be availabe in $DEST\n";
}

unless (-d $DEST) {
    print "Creating $DEST\n";
    mkdir $DEST or die "Cannot create $DEST: $!"
}


my $TMPDIR = "/tmp/zentyal-package-$$";

my $cwd;
my $pkgVersion;

my $SOURCE_BUILD = $ENV{SOURCE_BUILD};

sub create_tmp
{
   if ( -d $TMPDIR) {
        system("rm -rf $TMPDIR/*");
   } else {
        mkdir $TMPDIR  or
            die "Cannot create temporal directory $DEST: $!";
   }
}

sub export
{
    my ($dir, $exportDir) = @_;

    system("cp -r $dir $exportDir");
    system("find $exportDir -name t | xargs rm -rf");
}

sub add_changelog_entry
{
    my ($dir) = @_;

    chdir($dir);
    my $version = `head -1 ChangeLog`;
    chomp ($version);

    if ($version eq 'HEAD') {
        my $previousVersion = `grep '^[0-9]' ChangeLog | head -1`;
        my ($major, $minor) = $previousVersion =~ /(\d+)\.(.*)/;
        my ($minor1, $minor2) = $minor =~ /(\d+)\.(\d+)/;
        if ($minor2) {
            $minor2++;
            $version = "$major.$minor1.$minor2";
        } else {
            $version = "$major.$minor.1";
        }
    }

    my $dist = `head -1 debian/changelog | cut -d' ' -f3 | cut -d';' -f1`;
    chomp ($dist);
    system("dch -b -v '$version' -D '$dist' --force-distribution 'New upstream release'");
}

sub build_package
{
    my ($dir) = @_;

    chdir($dir);

    my $cmd= "dpkg-buildpackage -rfakeroot -us -uc";

    if ($SOURCE_BUILD) {
        $cmd .= ' -S';
    }

    system($cmd)
         and die "couldn't create package";
}

sub copy_to_dest
{
    my ($dir) = @_;

    system("cp ../*.* $DEST") and die "couldn't copy to repository";
}

sub generate_rep
{
    chdir ($DEST);

    system("apt-ftparchive packages . > Packages")
                                and die "couldn't generate pkg";
#    system("gzip -f Packages");
    system("apt-ftparchive sources . > Sources")
                                and die "couldn't generate src";
#    system("gzip -f Sources");
    system("apt-ftparchive release . > Release")
                                and die "couldn't generate release";
}

sub clean
{
    system ("rm -rf $TMPDIR");
    chdir $cwd;
}

sub packageIt
{
    my ($package) = @_;

    $cwd = getcwd;

    my ($dir, $exportDir);

    unless (defined $package) {
        $package = basename($cwd);
        unless (-d 'debian') {
            die "not in a package directory";
        }
        chdir '..';
        $REPO = getcwd;
    }

    if ($package eq 'all') {
        my @packages;

        foreach my $pkg (<*>) {
            if (-d "$pkg") {
                push(@packages, $pkg);
            }
        }
        foreach my $pkg (@packages) {
            print "Packaging $pkg...\n";
            system("$0 $pkg");
        }
        exit;
    } else {
        $dir = "$REPO/$package";
    }

    $exportDir = "$TMPDIR/$package";

    die "package does not exists" unless (-e $dir);

    export($dir, $exportDir);

    unless ($ENV{NOT_INCREMENT_CHANGELOG}) {
        add_changelog_entry($exportDir);
    }

    build_package($exportDir);

    copy_to_dest($exportDir);

    generate_rep();
}

try {
    create_tmp();
    packageIt($ARGV[0]);
    clean();
} otherwise {
    my $ex = shift;
    print $ex;
} finally {
    clean();
};
