#!/usr/bin/perl

use strict;
use warnings;

use utf8;

use open qw/:std :encoding(UTF-8)/;

use Yandex::Svn;
use ProjectSpecific qw/svn_url/;
use Path::Tiny qw/tempdir/;
use Yandex::Shell;
use Getopt::Long;
use Startrek::Client::Easy;

$Yandex::Shell::PRINT_COMMANDS = 1;

our $usage = <<EOF;
Отправить дифф между веткой и транком на ревью в Арканум.

# создать ревью ветки my-branch с названием из описания тикета DIRECT-12345
$0 --branch my-branch --ticket DIRECT-12345
# создать ревью ветки my-branch со своим названием. Название должно содержать номер тикета
$0 --branch my-branch --message "DIRECT-12345: fix things"
# В конце напишет ссылку на ревью с номером, например: https://a.yandex-team.ru/review/788923
# 788923 -- это id ревью, которое можно использовать для обновления.

# обновить ревью 788923
$0 --branch my-branch --update 788923

Опции:
--branch/-b
--message/-m
--ticket/-t
--help/-h
--update/-u
EOF

run() unless caller();

sub run {
    my $branch;
    my $review_id;
    my $message;
    my $ticket_id;
    GetOptions(
        'b|branch=s' => \$branch,
        'u|update=i' => \$review_id,
        'm|message=s' => \$message,
        't|ticket=s' => \$ticket_id,
        'h|help' => sub { print $usage; exit 0 },
    ) || die "can't parse options, stop\n";
    if (!$branch) {
        die "error: no branch\n";
    }
    if (!$review_id && !$message && !$ticket_id) {
        die "error: need --update or --message/--ticket\n";
    }
    if ($review_id && ($message || $ticket_id)) {
        warn "warning: message/ticket are ignored on update\n";
    }
    if ($message && $ticket_id) {
        die "error: --message and --ticket are mutually exclusive\n";
    }
    if ($ticket_id) {
        my $st = Startrek::Client::Easy->new();
        my $ticket = $st->get(key => $ticket_id);
        die "error: no ticket $ticket_id\n" unless $ticket;
        $message = "$ticket->{key}: $ticket->{summary}";
    }
    if (!$review_id && $message !~ /\bDIRECT-[0-9]+\b/) {
        die "error: invalid message, must contain ticket key\n";
    }
    if (!index($branch, svn_url('branches')) == 0) {
        $branch = svn_url('branch' => $branch);
    }
    my $rev = Yandex::Svn::svn_info($branch)->{revision};
    my $mergeinfo = `svn propget svn:mergeinfo '$branch'\@'$rev'`;
    my $last_merged_trunk_rev;
    if ( $mergeinfo =~ m!/trunk/arcadia/direct/perl:[0-9]+-([0-9]+)! ) {
        $last_merged_trunk_rev = $1;
    } elsif ( $mergeinfo =~ m!/migration/svn/direct/trunk:[0-9]+-([0-9]+)! ) {
        $last_merged_trunk_rev = $1;
    } else {
        my $log = `svn log '$branch'\@'$rev' --stop-on-copy -r 1:HEAD --limit 1`;
        if ( $log =~ /^r(\d+) /xsm ) {
            $last_merged_trunk_rev = $1;
        }
    }
    my $tempdir = tempdir("ya-clone-for-review.XXXXXX", DIR => "/tmp/temp-ttl/ttl_1d", CLEANUP => 1);
    print "$tempdir\n";

    yash_system "svn cat svn+ssh://arcadia.yandex.ru/arc/trunk/arcadia/ya > $tempdir/ya; chmod +x $tempdir/ya";
    yash_system "$tempdir/ya clone -r '$last_merged_trunk_rev' $tempdir/arcadia > /dev/null";

    chdir "$tempdir/arcadia";
    yash_system "$tempdir/ya svn up -q --set-depth empty direct";
    yash_system "$tempdir/ya svn up -q --set-depth empty direct/perl";
    yash_system "$tempdir/ya svn up -q --set-depth infinity direct/perl";

    my $trunk_url = svn_url('trunk');
    yash_system "$tempdir/ya svn diff $trunk_url\@$last_merged_trunk_rev $branch\@$rev > $tempdir/patch";

    chdir "$tempdir/arcadia/direct/perl";
    yash_system "$tempdir/ya svn patch $tempdir/patch";

    if (!$review_id) {
        yash_system "$tempdir/ya", 'pr', 'create', '-m', $message;
    } else {
        yash_system "$tempdir/ya", 'pr', 'update', '-i', $review_id;
    }
    chdir '/tmp'; # для cleanup
}

1;

