#!/usr/bin/env perl
use strict;
use warnings;

use MYDan;
use YAML::XS;
use Digest::MD5;
use MYDan::Agent::FileCache;
use File::Basename;
use MYDan::Util::FastMD5;

local $/ = undef;

my %param = %{ YAML::XS::Load( <> ) };

my $conf = $param{argv};

my $path = delete $conf->{path};

my $idie = sub{ print shift;exit 1; };
my $unlink = sub { unlink shift; print shift; exit 1 };

&$idie( "MYDanExtractFile undef" ) unless my $MYDanExtractFile = $ENV{MYDanExtractFile};

my $do = 1;
my $filecache = MYDan::Agent::FileCache->new();
if( $filecache->usable() && -f $path )
{
    my $md5 = eval{ MYDan::Util::FastMD5->hexdigest( $path ) };
    &$idie( "fastmd5 fail: $@" ) if $@;

    if( $md5 eq $conf->{md5} )
    {
        $do = 0;
        $do = 1 if $conf->{chmod}
             && ! chmod oct $conf->{chmod}, $path;
        $do = 1 if $conf->{chown} && ! ( my @pw = getpwnam $conf->{chown} );
        $do = 1 if @pw && ! chown @pw[2,3], $path;
    }
}

if( $do )
{
    my $tmp = "$MYDan::PATH/tmp";
    unless( -d $tmp ){ mkdir $tmp;chmod 0777, $tmp; }
    $tmp .= '/dump.data.';
    for my $f ( grep{ -f } glob "$tmp*" )
    {
        my $t = ( stat $f )[9];
        unlink $f if $t && $t < time - 3600;
    }

    my $temp = $tmp. Digest::MD5->new->add( sprintf "$path.%d.%stmp",  time, $$ )->hexdigest;

    &$idie( 'param error' ) unless defined $conf->{md5} && $path;
    &$idie( "get $conf->{chown} uid fail" ) if $conf->{chown} && ! ( my @pw = getpwnam $conf->{chown} );

    &$unlink( $temp, "save fail: $!" ) if system "mv '$MYDanExtractFile' '$temp'";
    my $md5 = eval{ MYDan::Util::FastMD5->hexdigest( $temp ) };
    &$idie( "fastmd5 fail MYDanExtractFile: $@" ) if $@;

    &$unlink( $temp, 'chomd fail' ) if $conf->{chmod}
         && ! chmod oct $conf->{chmod}, $temp;
    &$unlink( $temp, 'chown fail' ) if @pw && ! chown @pw[2,3], $temp;

    &$unlink( $temp, 'md5 nomatch' ) if $md5 ne $conf->{md5};

    my $dir = File::Basename::dirname( $path );
    unless( -d $dir )
    {
        &$unlink( $temp, 'mkdir dir fail' ) if system "mkdir -p '$dir'";
    }
    
    &$unlink( $temp, 'dst path error' )  if -e $path && ! -f $path;
    &$unlink( $temp, 'rename fail' ) if system "mv '$temp' '$path'";

    eval{ $filecache->save( $path ) unless $filecache->check( $md5 ); };
    print "filecache save fail:$@" if $@;
}

print "ok\n";
exit 0;
