#!/usr/bin/perl

use strict;
use warnings;

use utf8;

use Fcntl qw(:flock);
use ProjectSpecific qw/svn_url/;
use Yandex::Shell;

our $TRUNK_CACHE_PATH = '/var/www/svn-trunk-cache';
our $LOCK_FILE_PATH = '/var/lock/svn-trunk-cache';

run() unless caller();

sub run {
    die "Usage: direct-svn-checkout <svn path> <directory>\n" if @ARGV != 2;
    my ($svn_path, $dest_path) = @ARGV;

    # 2019-03
    # заменяем всю кастомную работу с кешированием на простой вызов svn co
    # потому что недавно externals заменили на закоммиченные файлы, и switch с транка на немерженные бранчи ломается
    # попозже, когда замена externals приедет в большинство бранчей, следующие 2 строчки можно удалить и тем вернуть "как было"
    # А может, после переезда в Аркадию все будет вообще по-другому
    yash_system "svn", "checkout", $svn_path, $dest_path;
    return 0;
    # конец патча про временное некеширование

    
    my $svn_root_url = svn_url('root');
    die "Incorrect SVN repository root, should be $svn_root_url" if index($svn_path, "$svn_root_url/") != 0;
    die "No trunk cache, directory $TRUNK_CACHE_PATH doesn't exist" unless -d $TRUNK_CACHE_PATH;
    die "Will not checkout to non-empty $dest_path" if -d $dest_path && !is_empty_dir($dest_path);
    my $dest_existed = -d $dest_path;

    if (!-f $LOCK_FILE_PATH) {      # такое может быть, например, после перезагрузки системы
        yash_system "touch", $LOCK_FILE_PATH;
    }

    open my $lock, "<", $LOCK_FILE_PATH or die "Cannot open $LOCK_FILE_PATH: $!";
    flock $lock, LOCK_SH or die "Cannot get a lock on $LOCK_FILE_PATH: $!";
    my $src_path = "$TRUNK_CACHE_PATH/.";
    yash_system("cp", "-r", $src_path, $dest_path);
    flock $lock, LOCK_UN or die "Cannot release a lock on $LOCK_FILE_PATH: $!";
    close $lock or die "Cannot close $LOCK_FILE_PATH: $!";
    system "svn", "switch", $svn_path, $dest_path;
    if ($?) {
        warn "svn switch failed, undoing changes\n";
        yash_system "rm -rf $dest_path/*";
        # rm -rf "$dest_path/*" не удалит файлы, начинающиеся с точки
        yash_system "rm -rf $dest_path/.??*";   # имена, начинающиеся с точки с длиной не меньше 3 символов
        yash_system "rm -rf $dest_path/.[!.]";  # имена, начинающиеся с точки из двух символов, кроме ".."
        if (! $dest_existed) {
            rmdir $dest_path;
        }
        die;
    }
    exit(0);
}

sub is_empty_dir {
    my $path = shift;
    my $is_empty = 1;
    opendir my $dh, $path or die "Cannot open $path: $!";
    while (readdir $dh) {
       unless (/^\.\.?\z/) {    # не . или ..
            $is_empty = 0;
            last;
        }
    }
    closedir $dh or die "Cannot close $path: $!";
    return $is_empty;
}
