# WWW::SourceForge.JP::Wiki
# by hylom
# This code is under GPL.
#

use LWP;
use HTTP::Cookies;
use HTTP::Request::Common;
use HTML::Entities;
use Encode;
use utf8;

package WWW::SourceForgeJP::Wiki;

sub new {
    my $class = shift @_;
    my $sf = shift @_;

    my $self = {
	'sf' => $sf,
	'_temp_page' => 'www-sfjp-wik-itemp',
    };

    return bless $self, $class;
}

sub _temp_page {
    my $self = shift @_;
    return $self->{_temp_page};
}

sub sf {
    my $self = shift @_;
    return $self->{sf};
}

sub _get_wikipage_url {
    my $self = shift @_;
    my $project = shift @_;
    my $page_name = shift @_;

    return "http://sourceforge.jp/projects/$project/wiki/$page_name";
}

sub get_page_list {
    my $self = shift @_;
    my $project = shift @_;

    my $url = $self->_get_wikipage_url( $project, $self->_temp_page );
    $url .= '?action=update';

    my $ua = $self->sf->lwp_ua;
    my $req_form = {
	'text' => '[[TitleIndex]]',
	'comment' => "",
	'do_preview' => '1',
    };

    my $resp = $ua->post( $url, $req_form );

    my $page_list_ref = [];

    my $content_string = $resp->content;
    my $list_str = "";
    $content_string =~ s/\n//mg;
    $content_string =~ s/\r//mg;
    $content_string =~ s/^.*<div[^>]*class="wiki-content"[^>]*>//;
    if( $content_string =~ m/<ul>(.*?)<\/ul>/m ) {
	$list_str = $1;
	while( $list_str ) {
	    if( $list_str =~ s/<li>(.*?)(<li>|<\/ul>|<\/li>)/$2/m ) {
		my $item = $1;
		my $page_name = "";
#		print $1, " - ", $2, "\n";
		if( $item =~ m/href=["'].*\/(.*?)["']/ ) {
		    $page_name = $1;
		    push @$page_list_ref, $page_name;
		}
	    } else {
		last;
	    }
	}
    }

    return $page_list_ref;
}


sub get_raw_text {
    my $self = shift @_;
    my $project = shift @_;
    my $page_name = shift @_;

    my $url = $self->_get_wikipage_url( $project, $page_name );
    $url .= '?action=edit';

    my $ua = $self->sf->lwp_ua;
    my $resp = $ua->get( $url );

    my $content = $resp->content;

    $content =~ s/.*<textarea.*?id="text".*?>//s;
    if( $content =~ m/(.*)<\/textarea>/s ) {
	$content = $1;
    }
    $content = HTML::Entities::decode_entities($content);
    return Encode::decode_utf8($content);

}

sub edit_page {
    my $self = shift @_;
    my %args = @_;

    my $project = $args{project};
    my $page_name = $args{page};
    my $text = $args{text};

    my $title = "";
    if( $args{title} ) {
	$title = $args{title};
    }
    my $comment = "";
    if( $args{comment} ) {
	$comment = $args{comment};
    }

#  print "$project - $page_name - $text - $comment";
    
    my $url = $self->_get_wikipage_url( $project, $page_name );
    $url .= '?action=update';

    my $ua = $self->sf->lwp_ua;
    my $req_form = {
	'text' => $text,
	'comment' => $comment,
	'title' => $title,
	'commit' => '1',
    };

    my $resp = $ua->post( $url, $req_form );
    if( $resp->is_error ) {
	return 0;
    } else {
	return 1;
    }
}

# delete_page( project_name, page_name )
sub delete_page {
    my $self = shift @_;
    my $project = shift @_;
    my $page_name = shift @_;

    my $url = $self->_get_wikipage_url( $project, $page_name );
    $url = "$url?action=delete";

    my $req_form = {
	'commit' => '1',
    };

    my $ua = $self->sf->lwp_ua;
    my $resp = $ua->post( $url, $req_form );

    if( $resp->is_error ) {
	return 0;
    } else {
	return 1;
    }
}


# post_attachment( <project_name>, <page_name>, <filename1>, <filename2>,... )
sub post_attachment {
    my $self = shift @_;
    my %args = @_;

    my $project = $args{project};
    my $page_name = $args{page};
    my $file_name = $args{file};


    my $url = $self->_get_wikipage_url( $project, $page_name );
    $url .= '/attach/!upload';

    my $ua = $self->sf->lwp_ua;

    my $req = HTTP::Request::Common::POST $url, Content_Type => 'form-data',
    Content => [ new_attach => ["$file_name"],
		 replace_file => "1",
		 commit => utf8::decode("アップロード"),
	];

    my $resp = $ua->request( $req );

    if( $resp->is_error ) {
	  print "error:", $resp->message, "\n";
	return 0; #print "upload $file_name: failed.\n";
    } else {
	return 1; #print "upload $file_name: succeed.\n";
    }
}

1;
