#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use open ':std' => ':utf8';
use Getopt::Long;
use Pod::Usage;

use Yandex::Shell;
use ProjectSpecific qw/svn_url/;
use Startrek::Client::Easy;

=encoding utf8
=head1 USAGE

    direct-svn-branch -t [DIRECT-]NNN [-n "my_cool_branch"]
    
    Создать ветку в svn, переключиться на нее, заполнить в тикете поле Бранч

    --ticket | -t <NNNN | DIRECT-NNNN> -- номер тикета, обязательно
    --name | -n branch_name -- имя ветки. Если не указано - используется транслитерация заголовка тикета. Имя бранча урезается до $MAX_BRANCH_NAME_LENGTH символов. 
    --parent-branch branch_name  -- ветка, от которой надо отвести новую (по умолчанию trunk)
    --dry -- запуск понарошку, не делать реальных изменений в svn и st
    --create | -c [PORT] -- после создания ветки создать бету, смотрящую на ветку (с помощью direct-create-beta)
    
    --help | -h -- Показать справку и выйти

=cut

my $MAX_BRANCH_NAME_LENGTH = 100;

my ($name, $ticket, $dry, $port);
GetOptions(
    "ticket|t=s" => \$ticket,
    "name|n=s" => \$name,
    "dry" => \$dry,
    "create|c:s" => \$port,
    "help|h" => sub { pod2usage(1) },
    "parent-branch=s" => \my $parent_branch,
) or pod2usage(1);

unless ($ticket) {
    pod2usage(1);
}

if ($ticket =~ /^\d+$/) {
    $ticket = ProjectSpecific::get_project_data('default_tracker_queue')."-$ticket";
}

my ($new_name, $summary) = get_branch_name_from_ticket($ticket);
$name //= $new_name;

my $branch_name = "$ticket-$name";
$branch_name = substr $branch_name, 0, $MAX_BRANCH_NAME_LENGTH;

my $from_branch = svn_url($parent_branch ? (branch => $parent_branch) : 'trunk');
my $branch = svn_url(branch => $branch_name);

my $message = qq#Branch for $ticket: $summary\n(via direct-svn-branch)#;

if (branch_exists($branch)) {
    print STDERR "branch $branch exists\n";
}
else {
    if ($dry) {
        print STDERR qq#svn cp $from_branch $branch -m "$message"\n#;
        if (!defined $port) {
            print STDERR qq#svn switch $branch\n#;
        }
    }
    else {
        yash_system svn => 'copy', $from_branch, $branch, q!-m! => $message;
        if (!defined $port) {
            yash_system svn => 'switch', $branch;
        }
    }
}

post_branch($ticket, $branch);

if (defined $port) {
    my @args = (
        '-b' => $branch_name,
    );
    if (length($port)) {
        push @args, "-p" => $port;
    }
    if ($dry) {
        my $args_str = join " ", @args;
        print STDERR "direct-create-beta $args_str\n";
    }
    else {
        yash_system 'direct-create-beta', @args;
    }
}

#####################

sub branch_exists
{
    my $branch = shift;
    my $ls = yash_qx("svn ls $branch 2>&1 || true");
    if ($ls =~ /non-existent in revision/) {
        return 0;
    }
    return 1;
}

sub get_branch_name_from_ticket
{
    my $ticket = shift;
    my $st = Startrek::Client::Easy->new();
    my $issue = $st->get(key => $ticket);
    if ($issue->{branch}) {
        print STDERR "WARNING: previous 'branch' value for $ticket: '$issue->{branch}'\n\n";
    }
    my $title = $issue->{summary};
    my %tr = (
        'А'  =>  'A',   'Б'  =>  'B',   'В'  =>  'V',     'Г'  =>  'G',    'Д'  =>  'D',     'Е'  =>  'E',   'Ж'  =>  'Zh',
        'З'  =>  'Z',   'И'  =>  'I',   'Й'  =>  'Y',     'К'  =>  'K',    'Л'  =>  'L',     'М'  =>  'M',   'Н'  =>  'N',
        'О'  =>  'O',   'П'  =>  'P',   'Р'  =>  'R',     'С'  =>  'S',    'Т'  =>  'T',     'У'  =>  'U',   'Ф'  =>  'F',
        'Х'  =>  'Kh',  'Ц'  =>  'Ts',  'Ч'  =>  'Ch',    'Ш'  =>  'Sh',   'Щ'  =>  'Shch',  'ъ'  =>  '',
        'ы'  =>  'y',   'ь'  =>  '',    'Э'  =>  'E',     'Ю'  =>  'Yu',   'Я'  =>  'Ya',    'а'  =>  'a',   'б'  =>  'b',
        'в'  =>  'v',   'г'  =>  'g',   'д'  =>  'd',     'е'  =>  'e',    'ж'  =>  'zh',    'з'  =>  'z',   'и'  =>  'i',
        'й'  =>  'y',   'к'  =>  'k',   'л'  =>  'l',     'м'  =>  'm',    'н'  =>  'n',     'о'  =>  'o',   'п'  =>  'p',
        'р'  =>  'r',   'с'  =>  's',   'т'  =>  't',     'у'  =>  'u',    'ф'  =>  'f',     'х'  =>  'kh',  'ц'  =>  'ts',
        'ч'  =>  'ch',  'ш'  =>  'sh',  'щ'  =>  'shch',  'э'  =>  'e',    'ю'  =>  'yu',    'я'  =>  'ya',
    );
    $title =~ s!([^a-zA-Z0-9_-])!$tr{$1} // '_'!ge;
    $title =~ s!_{2,}!_!g;
    $title =~ s!^_+|_+$!!g;
    $title = lc $title;
    return ($title, $issue->{summary});
}

sub post_branch
{
    my ($ticket, $branch) = @_;
    
    return if $dry;

    $branch =~ s!.*/!!;
    my $st = Startrek::Client::Easy->new();
    $st->do(key => $ticket, branch => $branch);
}

