#!/usr/bin/perl

=head1 NAME

    direct-delete-beta

=head1 DESCRIPTION

    удаление беты по заданному пути (direct-mk prerm + rm -rf)

=head1 SYNOPSIS

    direct-delete-beta /var/www/beta.yukaba.8420

    betas 8420 -d | xargs direct-delete-beta    # удалить бету на порту 8420
    betas `whoami` 'branches/my-branch$' | awk '{print $1}' | xargs direct-delete-beta  # удалить все беты, смотрящие на бранч my-branch

=cut

use strict;
use warnings;

use utf8;

use Cwd qw/abs_path/;
use Getopt::Long;

use ProjectSpecific qw/svn_url/;
use Yandex::Svn qw/svn_info/;

my $SVN_ROOT = svn_url('root');

my $FORCE;
GetOptions(
    "force|f" => \$FORCE,
);

run() unless caller();

sub run {
    die "usage: direct-delete-beta [-f] <path>\n" unless $ARGV[0];
    my $path = abs_path($ARGV[0]);

    my $is_arc = is_beta_path_arc($path);

    if ($FORCE && !is_beta_path($path)) {
        die "doesn't looks like beta directory, should be '/var/www/beta.*'";
    } elsif (!$FORCE && !$is_arc && !is_beta_path_svn($path)) {
        die "repository root for working copy should be $SVN_ROOT\n"
    }

    chdir $path;
    system "direct-mk", "beta-prerm";

    my @procs;
    foreach (1..5) {
      sleep 2;
      @procs = get_beta_procs($path);
      warn "can't delete $path, the following processes are still running:\n" . join("\n", @procs) if @procs;

      last if !scalar @procs;
    }

    if (!$FORCE && @procs) {
        die "can't delete $path, the following processes are still running:\n" . join("\n", @procs)
    } elsif (@procs) {
        my @pids = get_beta_pids($path);
        print STDERR "failed to stop beta web-servers, killing pids: [".(join ", ", @pids)."]\n";
        kill 'TERM', @pids;
    }

    if ($is_arc) {
        my $unmount_output = `arc unmount "$path/arcadia" 2>&1`;
        if ($? && $unmount_output !~ /already unmounted/) {
            die "Failed to unmount repository:\n$unmount_output";
        }
    }

    system "rm", "-rf", $path;
    exit 0;
}

sub get_beta_procs {
    my $path = shift;
    my @procs = grep { /(apache2?|nginx).*\Q$path\E/ } map {chomp; $_} `ps x`;
    return @procs;
}

sub get_beta_pids {
    my $path = shift;
    my @procs = get_beta_procs($path);
    my @pids = grep {defined $_ } map {/^\s*(\d+)\s/ && $1} @procs;
    return @pids;
}

sub is_beta_path_svn {
    my $path = shift;
    my $svn_info = svn_info($path);
    # после переезда в Аркадию старые беты не удалялись без -force, потому что смотрели на "чужой" репозиторий. Разрешаем их удалять
    return ($svn_info->{repository_root} eq $SVN_ROOT) || ( $svn_info->{repository_root} eq 'svn+ssh://svn.yandex.ru/direct' );
}

sub is_beta_path_arc {
    my $path = shift;
    # смотреть на store не очень надежно, но репозиторий уже может быть размаунчен, и честно проверить не получится
    return 1 if -d "$path/store";
    return 1 if -l "$path/arcadia/.arc";
    return 0;
}

sub is_beta_path {
    my $path = shift;
    return $path =~ m!^/var/www/beta\.([\w\-]+?)\.?\d{4,5}+$!;
}

