#!/usr/bin/perl -w
#
# Copyright (C) 2004, 2005, 2006, 2008  Alex Schroeder <alex@gnu.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.

require LWP;
use Getopt::Std;

our ($opt_v, $opt_w);

# We make our own specialization of LWP::UserAgent that asks for
# user/password if document is protected.
{
  package RequestAgent;
  @ISA = qw(LWP::UserAgent);

  sub new {
    my $self = LWP::UserAgent::new(@_);
    $self;
  }

  sub get_basic_credentials {
    my($self, $realm, $uri) = @_;
    return split(':', $main::opt_w, 2);
  }
}

my $usage = qq{$0 [-f] [-m] [-s SUMMARY]
\t[-u USERNAME] [-p PASSWORD] [-w USERNAME:PASSWORD]
\t[-q QUESTION] [-a ANSWER] [-z SECRET]
\tTARGET

Post the data on stdin on the wikipage described by wikipage.

TARGET is the URL for the wiki page.

Options:

 -f	Allow the posting of empty pages (default: no)
 -m     Whether this is a minor edit (default: no)

Options with arguments:

 -s	The summary for RecentChanges (default: none)
 -u     The username for RecentChanges (default: none)
 -p     The password to use for locked pages (default: none)
 -w     The username:password combo for basic authentication (default:none)
 -q     The question number to answer (default: 0, ie. the first question)
 -a     The answer to the question (default: none)
 -z     Alternatively, the secret key (default: question)
 -v     Verbose output for debugging (default: none)

The defaults are chosen such that if the QuestionAsker extension is
used and the secret key is unchanged, there is no need to provide
either secret key or password.

If the target wiki is protected by so-called "basic authentication" --
that is, if you need to provide a username and password before you can
even view the site -- then you can pass those along using the -w
option. Separate username and password using a colon.
};

sub post {
  my ($uri, $id, $data, $minor, $summary, $username, $password,
      $question, $answer, $secret) = @_;
  my $ua = RequestAgent->new;
  my %params = (title=>$id, text=>$data, raw=>1,
		username=>$username, pwd=>$password,
		summary=>$summary, question_num=>$question,
		answer=>$answer, $secret=>1,
		recent_edit=>$minor);
  if ($opt_v) {
    foreach my $key (keys %params) {
      my $value = $params{$key} || '(none)';
      $value = substr($value,0,50) . '...'
	if $key eq 'text' and length($value) > 53;
      warn "$key: $value\n";
    }
  }
  my $response = $ua->post($uri, \%params);
  my $status = $response->code . ' ' . $response->message;
  warn "POST $id failed: $status.\n" unless $response->is_success;
}

sub main {
  # $opt_v, $opt_w are global
  our($opt_f, $opt_m, $opt_s, $opt_u, $opt_p, $opt_q, $opt_a, $opt_z);
  getopts('fms:u:p:q:a:z:vw:');
  my $target = shift @ARGV;
  die $usage if not $target or @ARGV; # not enough or too many
  die "Cannot determine page id from $target\n" unless $target =~ m!^(.*)[/?](.*?)$!;
  my ($uri, $id) = ($1, $2);
  warn "id $id" if $opt_v;
  undef $/;
  my $data = <STDIN>;
  die "No content to post or use -f to force it\n" if not $data and not $opt_f;
  warn length($data) . " bytes of data" if $opt_v;
  post ($uri, $id, $data, $opt_m ? 'on' : '', $opt_s, $opt_u, $opt_p,
	$opt_q, $opt_a, $opt_z||'question');
}

main();
