#!/usr/bin/perl

use warnings;
use strict;
use IkiWiki;

package IkiWiki;

sub rcs_update () {
}

sub rcs_prepedit ($) {
    return ""
}

sub rcs_commit ($$$;$$) {
    return undef # success
}

sub rcs_add ($) {
}

# FIXME the stuff here is rather site-specific...
sub recentchanges_filter($) {
    my $p = shift;
    return undef if $p !~ /^source/;
    $p =~ s,^source/,,;
    return $p;
}

sub rcs_recentchanges ($) {
    my $num=shift;
    my @ret;

    eval q{use Date::Parse};
    eval q{use XML::Simple};

    my $repodir=$config{srcdir};

    debug("darcs recent changes: $num");

    my $child = open(LOG, "-|");
    if (! $child) {
        $ENV{"DARCS_DONT_ESCAPE_ANYTHING"}=1;
        exec("darcs", "changes", "--xml", 
            "--summary",
             "--repodir", "$repodir",
             "--last", "$num")
        || error("darcs changes failed to run");
    }
    my $data;
    $data .= $_ while(<LOG>);
    close LOG;

    my $log = XMLin($data, ForceArray => 1);

    debug("parsing recent changes...");
    foreach my $patch (@{$log->{patch}}) {
        my $date=$patch->{local_date};
        my $hash=$patch->{hash};
        my $when=str2time($date);
        my (@pages, @pg);
        push @pages, $_ for (@{$patch->{summary}->[0]->{modify_file}});
        push @pages, $_ for (@{$patch->{summary}->[0]->{add_file}});
        push @pages, $_ for (@{$patch->{summary}->[0]->{remove_file}});
        for (@pages) {
            my $p = $_;
            $p = $_->{content} if (ref $_);
            $p =~ s,^\s+,,; $p =~ s,\s+$,,; # cut whitespace

            $p = recentchanges_filter($p);
            next unless defined $p;

            debug("page: $p");
            push @pg, {
                page => pagename($p)
            };
        }
        next unless (scalar @pg > 0);
        debug("recent change: " . $patch->{name}[0] . " ("
            . scalar @pg . " changes)");

        my @message;
        push @message, { line => $_ } for (@{$patch->{name}});

        push @ret, {
            rev => $patch->{hash},
            user => $patch->{author},
            committype => "darcs", # FIXME
            when => $when, 
            message => [@message],
            pages => [@pg],
        };
    }

    return @ret;
}

our %cache;

sub loadcache () {
    my $repodir=$config{srcdir};
    if (!defined %cache) {
        my $f = "$repodir/.ikiwiki.ctimes";
        if (-s "$f") {
            my $VAR1;
            my $x = `cat "$f"`;
            $x =~ /^(.*)$/sm; # untaint
            eval "$1";
            %cache = %$VAR1;
        }
    }
}

sub rcs_getctime ($) {
    my $file=shift;

    eval q{use Date::Parse};
    eval q{use XML::Simple};
    local $/=undef;

    # Sigh... doing things the hard way again
    my $repodir=$config{srcdir};

    &loadcache;

    my $filer=substr($file, length($repodir));
    $filer =~ s:^[/]+::;

    if (defined $cache{$filer}) {
        #debug("taking cached ctime ".localtime($cache{$filer})." for $filer");
        return $cache{$filer};
    }

    my $child = open(LOG, "-|");
    if (! $child) {
        exec("darcs", "changes", "--xml", "--reverse",
             "--repodir", "$repodir", "$filer")
        || error("darcs changes $filer failed to run");
    }

    my $data;
    $data .= $_ while(<LOG>);
    close LOG;

    my $log = XMLin($data, ForceArray => 1);

    my $datestr=$log->{patch}[0]->{local_date};

    if (! defined $datestr) {
        warn "failed to get ctime for $filer";
        $cache{$filer} = 0;
        return 0;
    }

    my $date=str2time($datestr);

    #debug("found ctime ".localtime($date)." for $filer");

    $cache{$filer} = $date;
    return $date;
}

END {
    my $repodir=$config{srcdir};
    if (defined %cache) {
        debug("dumping ctime cache to $repodir/.ikiwiki.ctimes");
        open CACHE, ">$repodir/.ikiwiki.ctimes";
        print CACHE Dumper(\%cache);
        close CACHE;
    }
}

1
