# Copyright 2002-2008 Josh Clark and Global Moxie, LLC. This code cannot be
# redistributed without permission from globalmoxie.com.  For more
# information, consult your Big Medium license.
#
# $Id: Maintenance.pm 3239 2008-08-22 14:59:28Z josh $

package BigMed::App::Web::Maintenance;
use strict;
use warnings;
use utf8;
use Carp;
$Carp::Verbose = 1;
use base qw(BigMed::App::Web);
use BigMed::Janitor;
use English qw( -no_match_vars );

sub setup {
    my $app = shift;
    $app->start_mode('update');
    $app->run_modes(
        'AUTOLOAD'    => sub { $_[0]->rm_update() },
        'update'      => 'rm_update',
        'ajax-update' => 'rm_ajax_update',
    );
    return;
}

sub rm_update {
    my $app     = shift;
    
    $| = 1; #no buffering
    print $app->_send_headers();

    #create a janitor object that will keep the connection alive
    #by pinging during page builds if necessary
    BigMed::Janitor->add_trigger('new_builder', \&_ping_browser);
    BigMed::Janitor->add_trigger('before_index', \&_ping_indexer);
    BigMed::Janitor->add_trigger('before_backup', \&_ping_backup);
    my $janitor = BigMed::Janitor->new();
    
    #send email on fatal error, log warnings.
    my $rerror = $SIG{__DIE__} = sub {
        #this gets ugly...
        #we don't want to do this handling on eval'd code.
        #because the whole op is wrapped in eval (via CGI::Application),
        #$^S testing prescribed by perldoc for 'die' won't work,
        #because $^S is always true -- *every* call is an eval call.
        #instead, test for callers that are eval and *not* cgi::app
        my $i = 0;
        my @fields;
        while (@fields = caller($i++) ) {
            die @_
              if $fields[3] eq '(eval)' && $fields[0] ne 'CGI::Application';
        }
    
        #otherwise, it's a regular death
        my $preamble = $app->language('MAINT_Error preamble');
        $app->log( alert =>"$preamble\n\n$_[0]" );
        exit(0);
    };
    $SIG{__WARN__} = sub { $app->log( info => "Janitor warned: $_[0]" ) };

    if (!$janitor->do_maintenance) { #caught an error
        my %err = $app->error_html_hash;
        $rerror->( $app->unescape( $app->language( $err{text} ) ) );
    }
    print "<br />OK\n";
    exit(0);
} 

sub _ping_browser {
    my ($janitor, $builder) = @_;
    $builder->add_trigger('fresh_section_context', \&_do_ping);
    $builder->add_trigger('level_midbuild', \&_do_ping);
    return 1;
}

sub _ping_indexer {
    my ($janitor, $search, $site) = @_;
    $search->indexer->add_trigger('mid_index', \&_do_ping);
    return 1;
}

sub _ping_backup {
    my ($janitor, $backup) = @_;
    $backup->add_trigger('after_moxiedata_dir', \&_do_ping);
    $backup->add_trigger('after_site_dir', \&_do_ping);
    $backup->add_trigger('after_theme_dir', \&_do_ping);
    return 1;
}

sub _do_ping {
    print '...';
    return 1;
}

sub rm_ajax_update {
    my $app     = shift;
    my $janitor = BigMed::Janitor->new();
    $janitor->do_maintenance or return $app->ajax_system_error;
    return $app->ajax_html( $app->language('MAINT_Maintenance complete') );
}

1;

__END__

