#!/usr/bin/perl -w
# $Id: distsync 27 2019-07-23 11:26:37Z abalama $
use strict;

=head1 NAME

distsync - launcher of synchronization via App::DistSync

=head1 SYNOPSIS

    distsync [options] [commands]

    distsync -D /var/www/dist init

    distsync [-d] -D /var/www/dist [-T TIMEOUT] [sync]

=head1 OPTIONS

=over 4

=item B<-d, --debug>

Enable debug mode

=item B<-D /path/to/directory, --dir=/path/to/directory>

Sets working directory

=item B<-h, --help>

Show short help information and quit

=item B<-H, --longhelp>

Show long help information and quit

=item B<-T secs, --timeout=secs>

Set timeout for HTTP requests

=item B<-V, --version>

Print the version number of the program and quit

=item B<-k secs, --keep=secs>

Max amount of seconds before breaking lock (0 for never, default is 3600)

=back

=head1 COMMANDS

=over 4

=item B<init>

Initializing the mirror in the specified directory

=item B<sync>

Synchronization of the specified directory with the remote resources (mirrors)

=back

=head1 DESCRIPTION

Launcher of synchronization via App::DistSync

See L<App::DistSync> for details

=head1 AUTHOR

Serz Minus (Sergey Lepenkov) L<http://www.serzik.com> E<lt>abalama@cpan.orgE<gt>

=head1 COPYRIGHT

Copyright (C) 1998-2019 D&D Corporation. All Rights Reserved

=head1 LICENSE

This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.

See L<https://dev.perl.org/licenses/>

=cut

use Getopt::Long;
use Pod::Usage;

use Cwd;
use File::Spec;

use App::DistSync;
use App::DistSync::Lock;

use constant {
    PIDFILE     => 'distsync.pid',
    CMDDEFAULT  => 'sync',
    COMMANDS    => [qw/ init sync /],
};

$SIG{INT} = sub { die "Aborted\n"; };

$| = 1;  # autoflush

our %OPT;

BEGIN {
    sub _say { return unless $OPT{debug} || -t; print STDOUT @_ ? @_ : '',"\n" }
    sub _err { print STDERR @_ ? @_ : '',"\n" }
    sub _tms { sprintf "[%s GMT]", scalar(gmtime(time())) }
}

Getopt::Long::Configure ("bundling");
GetOptions(\%OPT,
    "help|usage|h",         # Show help page
    "longhelp|H|?",         # Show long help page
    "version|vers|ver|V",   # Print VERSION of the App::MBUtiny
    "debug|d",              # Debug mode

    "directory|dir|D=s",    # Directory
    "timeout|T=s",          # Timeout
    "hold|keep|k=i",        # Hold value. 0 - off, 1-n - secs, default - 3600
) || pod2usage(-exitval => 1, -verbose => 0, -output => \*STDERR);
pod2usage(-exitval => 0, -verbose => 1) if $OPT{help};
pod2usage(-exitval => 0, -verbose => 2) if $OPT{longhelp};
printf("Version: %s\n", App::DistSync->VERSION) && exit(0) if $OPT{version};

# VARS
my %cmddata;
my $command   = @ARGV ? shift @ARGV : CMDDEFAULT;
my @argss = @ARGV ? @ARGV : ();
my @commands  = @{(COMMANDS)};
pod2usage(-exitval => 1, -verbose => 99, -sections => 'SYNOPSIS|OPTIONS|COMMANDS', -output => \*STDERR)
    if ( (grep {$_ eq $command} @commands) ? 0 : 1 );

# Directory
my $root_dir = $OPT{directory} || cwd();
unless ($root_dir && (-e $root_dir) && (-d $root_dir or -l $root_dir)) {
    _err(sprintf "Directory \"%s\" not exists", $root_dir || '.');
    exit(1);
}

# Debugging
$App::DistSync::DEBUG = 1 if $OPT{debug};

_say sprintf("App::DistSync/%s", App::DistSync->VERSION);
_say;
my $start_tms = _tms;
START: debug("START ", _tms);
#########################
### START
#########################

# LOCK & PID
my $lock = new App::DistSync::Lock(
        file => File::Spec->catfile($root_dir, App::DistSync::MANILOCK()),
        hold => $OPT{hold},
        pid  => $$,
    );
if (!$lock->status || $lock->running) {
    _err($lock->error);
    goto FINISH;
}

# Main object
my $ds = new App::DistSync(
        dir => $root_dir,
        pid => $$,
        timeout => $OPT{timeout},
    );

if ($command eq 'init') {
    goto FINISH unless $ds->init;
    _say sprintf "Initialization has been completed. Your files located in %s", $root_dir;
} else {
    my $status = $ds->sync;
    if ($status) {
        _say(sprintf("Sync completed successfully\n\tURI:\t\t%s\n\tDirectory:\t%s\n\tStarted at:\t%s\n\tFinished at:\t%s",
            (defined($ds->{uri}) ? $ds->{uri} : 'none'),
            $root_dir,
            $start_tms,
            _tms
        ));
    } else {
        _say(sprintf("Sync completed with errors\n\tDirectory:\t%s", $root_dir));
    }
}

#########################
### FINISH
#########################
FINISH: debug("FINISH ", _tms);
exit(0);

1;

__END__
