#!/usr/bin/perl -w

# $Id$

=head1 DESCRIPTION

Показывает версию сборки текущей рабочей копии.

Опции:

=over 2

=item dir

=item deb-root

=item dirty

=item next

=back

=cut

use 5.010;
use strict;
use warnings;
use utf8;

use Getopt::Long;
use IPC::Open2;
use File::Slurp;


run() if !caller();


sub run {
    my %opt;
    GetOptions(
        'dir=s'      => \$opt{dir},
        'deb-root=s' => \$opt{deb_root},
        'dirty!'     => \$opt{dirty},
        'next!'      => \$opt{next},
        'h|help|usage' => \&usage,
    );

    $opt{dir} //= $ARGV[0];
    $opt{deb_root} //= $ARGV[1];

    print get_package_version(%opt);
    exit;
}


sub get_package_version {
    my %opt = @_;

    my $dir= $opt{dir} || q{.};
    my %SVN_INFO = svn_info($dir);
    my $version = $SVN_INFO{Revision};

    my $BRANCH_RE = qr!trunk|releases/release-\d+|(?:tags|branches)/[a-z0-9\-\_\.]+|limtest/[a-z0-9\-\_\.]+-\d+-\d+!;
    my ($svn_root, $branch, $insvn_path) = $SVN_INFO{URL} =~ m!^ (.*?) / ($BRANCH_RE) /? ([\w\-\_\.\/]*)? $!ix;
    die "Incorrect SVN URL: $SVN_INFO{URL}"  if !$svn_root;

    $insvn_path =~ s#/?$#/#;
    my $insvn_level = $insvn_path =~ m#./#gx;
    my $wc_root = $dir . ("/.." x $insvn_level);

    if ($branch eq 'trunk' || $branch eq 'lego') {
        # trunk
        $version = "1.$version";
    } elsif ($branch =~ /^releases\/release-(\d+)$/) {
        # releases/release-NNN
        $version = "1.$1.$version";
    } elsif ($branch =~ /^(?:branches|tags)\/(.*)$/) {
        # branches|tags
        my $name = $1;
        $name =~ s/_/-/g;
        my $res = my_qx(svn => 'mergeinfo', '--show-revs' => 'eligible', "$svn_root/trunk", $wc_root);
        my $base_revision = $res =~ /^r(\d+)/ ? $1-1 : $version;
        $version = $base_revision == $version ? "1.$version~$name" : "1.$base_revision.$version~$name";
    } else {
        die "Unrecognizable branch $branch";
    }

    # todo: не предполагать директ
    my $debian_root = $opt{deb_root} || "$wc_root/packages/yandex-direct/debian/";


    my $version_file = "$debian_root/version";
    if (-f $version_file && scalar(read_file($version_file)) =~ /^$version-(\d+)(~\w+)?$/) {
        $version = "$version-" . ($1 + !!$opt{next} );
    } else {
        $version = "$version-1";
    }
    
    if ($opt{dirty}) {
        my $sep = $version =~ /~/ ? '-' : '~';
        $version =~ s/-1$/${sep}dirty-1/;
    }

    return $version;
}


sub svn_info {
    my ($path) = @_;
    return
        map {/^([^:]+):\s*(.*)/ ? ($1 => $2) : ()}
        split /\n/, my_qx("svn", "info", $path);
}


sub my_qx {
    my ($in_fh, $out_fh);
    my $pid = open2($out_fh, $in_fh, @_);
    my $txt = join(", ", map {"'$_'"} @_);
    if (!$pid) {
        die "Can't open $txt: $!";
    }
    my $buffer = join '', <$out_fh>;
    my $ret = waitpid($pid, 0);
    if ($ret != $pid) {
        die "Error: can't wait child $txt";
    }
    if ($?) {
        die "Error: child return error: $?, $!";
    }
    return $buffer;
}


sub usage {
    system("podselect -section NAME -section SYNOPSIS -section DESCRIPTION $0 | pod2text-utf8 >&2");
    exit;
}
