The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
#!/usr/bin/perl

use strict;
use warnings;
use Getopt::Long qw( GetOptions );
use IO::Interactive qw( is_interactive );
use List::Util   qw( first );
use Try::Tiny;

use FindBin;
use lib "$FindBin::Bin/../lib";
use Games::Lacuna::Client ();

my @old_planet;
my @station;
my @ignore;
my @ignore_regex;
my @pass;
my $help;

GetOptions(
    'planet=s@'       => \@old_planet,
    'station=s@'      => \@station,
    'ignore=s@'       => \@ignore,
	'ignore-regex=s@' => \@ignore_regex,
    'pass=s@'         => \@pass,
    'help|h'          => \$help,
);

usage() if $help;

die "--planet opt has been renamed to --station\n"
    if @old_planet;

my $cfg_file = shift(@ARGV) || 'lacuna.yml';
unless ( $cfg_file and -e $cfg_file ) {
  $cfg_file = eval{
    require File::HomeDir;
    require File::Spec;
    my $dist = File::HomeDir->my_dist_config('Games-Lacuna-Client');
    File::Spec->catfile(
      $dist,
      'login.yml'
    ) if $dist;
  };
  unless ( $cfg_file and -e $cfg_file ) {
    die "Did not provide a config file";
  }
}

my $is_interactive = is_interactive();

my $client = Games::Lacuna::Client->new(
	cfg_file  => $cfg_file,
	rpc_sleep => 2,
);

# Load the planets
my $empire  = $client->empire->get_status->{empire};

# reverse hash, to key by name instead of id
my %planets = reverse %{ $empire->{planets} };

SS:
for my $name ( sort keys %planets ) {
    next if @station && !grep { lc $name eq lc $_ } @station;

    next if @ignore && first { lc $name eq lc $_ } @ignore;

	next if @ignore_regex && first { $name =~ m/$_/i } @ignore_regex;

    my $planet = $client->body( id => $planets{$name} );

    my $result = $planet->get_buildings;

    next if $result->{status}{body}{type} ne 'space station';

    printf "Space Station: %s\n\n", $result->{status}{body}{name};

    my $buildings = $result->{buildings};

    my $parliament_id = first {
            $buildings->{$_}->{url} eq '/parliament'
        } keys %$buildings;

    next if !defined $parliament_id;

    my $parliament = $client->building( id => $parliament_id, type => 'Parliament' );

    my $propositions;

    try {
        $propositions = $parliament->view_propositions->{propositions};
    }
    catch {
        warn "$_\n\n\n";
        no warnings 'exiting';
        next SS;
    };

    if ( ! @$propositions ) {
        print "No propositions\n\n\n";
        next;
    }

    for my $prop ( @$propositions ) {
        printf "%s\n", $prop->{description};
        printf "Proposed by: %s\n", $prop->{proposed_by}{name};
        printf "Will automatically pass at: %s\n", $prop->{date_ends};
        printf "Votes needed: %d\n", $prop->{votes_needed};
        printf "Votes so far: %d yes, %d no\n",
            $prop->{votes_yes},
            $prop->{votes_no};

        if ( exists $prop->{my_vote} ) {
            printf "You have already voted: %s\n\n",
                $prop->{my_vote} ? 'yes' : 'no';
            next;
        }

        my $vote;

        if ( @pass && first { $prop->{description} =~ /$_/i } @pass ) {
            print "AUTO-VOTED YES\n";
            $vote = 1;
        }
        elsif ( $is_interactive ) {
            while ( !defined $vote ) {
                print "Vote yes or no: ";
                my $input = <STDIN>;

                if ( $input =~ /y(es)?/i ) {
                    $vote = 1;
                }
                elsif ( $input =~ /no?/i ) {
                    $vote = 0;
                }
                else {
                    print "Sorry, don't understand - vote again\n";
                }
            }
        }
        else {
            print "Non-interactive terminal - skipping proposition\n";
            next;
        }

        $parliament->cast_vote( $prop->{id}, $vote );
        print "\n\n";
    }
}

exit;


sub usage {
    die <<"END_USAGE";
Usage: $0 CONFIG_FILE

Prompts for vote on each proposition.

Options:
    --station STATION NAME

Multiple --station opts may be provided.
If no --station opts are provided, will search for all allied space-stations.

    --ignore PLANET/STATION NAME
Save RPCs by specifying your planet names, so we don't have to get its status
from the server to find that out.

    --ignore-regex REGEX
Similar to --ignore above, but used as a case-insensitive regular expression,
rather than an exact match.

    --pass REGEX
Multiple --pass opts may be provided - these are run as regexes against each
proposition description - if it matches, the proposition is automatically
voted 'yes'.

Changes:
The --planet opt has been renamed to --station.
Using --planet will throw an error.

END_USAGE

}