use strict;
use warnings;
use experimental 'signatures';
use IO::Socket::SSL;
use LWP::UserAgent;
use Encode;
use Irssi;
use Irssi::TextUI;

our $VERSION = "0.3"; # a565a40ad05861e
our %IRSSI = (
    authors     => 'Nei',
    contact     => 'Nei @ anti@conference.jabber.teamidiot.de',
    url         => "http://anti.teamidiot.de/",
    name        => 'pastebin',
    description => 'Simple script to redirect pastes to a pastebin.',
    license     => 'GNU GPLv2 or later',
   );
die "This script requires Irssi 1.4 or later"
    if (Irssi::parse_special('$abiversion')||0) < 44;

my $utf8;
my $provider;

my $tmout = 10;

sub gui_input_get () {
    Irssi::parse_special('$L')
}

sub run_next ($subname, $arg) {
    Irssi::timeout_add_once(10, $subname, $arg);
}

my @pastebin = (
    # opensuse
    sub ($name, $paste) {
	my $base_url = 'https://paste.opensuse.org/';
	my $ua = LWP::UserAgent->new(
	    agent => "irssi-pastebin/$VERSION ",
	    env_proxy => 1,
	    timeout => $tmout,
	   );
	my $res = $ua->post($base_url, {
	    name => $name,
	    lang => 'text',
	    code => $paste,
	    submit => 'submit',
	    api_key => '',
	    expire => '10080',
	    title => '',
	});
	if ($res->code == 302) {
	    my $loc = $res->header('location');
	    return (0, 'invalid redirect')
		if $loc !~ /^\Q$base_url/;

	    $res = $ua->get($loc);
	    return (0, 'pasted content not supported by pastebin')
		if $res->code == 404;
	    return (1, $loc) if
		$res->code == 200;
	    return (0, $res->status_line);
	}
	else {
	    return (0, $res->status_line);
	}
    },
    # tcp.st
    sub ($name, $paste) {
	local $@;
	my $cl = IO::Socket::SSL->new(
	    PeerHost => 'tcp.st',
	    PeerPort => '8777',
	    Timeout => $tmout,
	   );
	return (0, "$@")
	    unless $cl;
	print $cl $paste;
	my $res = <$cl>;
	return (0, "$!")
	    unless defined $res;
	chomp $res;
	my ($k, $v) = split ' ', $res, 2;
	return (1, $v)
	    if $k eq 'URL';
	return (0, $v);
    }
   );

sub insert_link ($loc) {
    my $input = gui_input_get();
    my $pos = Irssi::gui_input_get_pos();
    Encode::_utf8_on($input)
	    if $utf8;
    $loc = " $loc"
	if $pos > 0;
    (substr $input, $pos, 0) = $loc;
    Irssi::gui_input_set($input);
    Irssi::gui_input_set_pos($pos + length $loc);
}

sub do_paste ($name, $paste) {
    my $win = Irssi::active_win;
    print STDERR " uploading...";
    my ($res, $loc) = $pastebin[$provider]($name, $paste);
    if ($res) {
	run_next('insert_link', $loc);
    } else {
	$win->print("Pastebin: upload failed... " . $loc);
    }
}

sub sig_paste_event ($paste, $arg) {
    my $win = Irssi::active_win;
    my $name = $win->{active_server} ?
	$win->{active_server}->parse_special('$N') :
	Irssi::parse_special('$nick');

    do_paste($name, $paste);
}

sub sig_setup_changed {
    $utf8 = lc Irssi::settings_get_str('term_charset') eq 'utf-8';
    $provider = Irssi::settings_get_choice('pastebin_provider');
}

Irssi::settings_add_choice('pastebin', 'pastebin_provider', 0, 'opensuse;tcp.st');

sig_setup_changed();

Irssi::signal_add('paste event', 'sig_paste_event');
Irssi::signal_add('setup changed', 'sig_setup_changed');
