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

use 5.006002;

use strict;
use warnings;

use Astro::SpaceTrack;
use Getopt::Long 2.33 qw{ :config auto_version };
use JSON;
use Pod::Usage;

our $VERSION = '0.111';

my %opt;

GetOptions( \%opt,
    qw{ identity! kelso_url|kelso-url|celestrak_url|celestrak-url=s
    password=s symbolic! tle! username=s },
    help => sub { pod2usage( { -verbose => 2 } ) },
) or pod2usage( { -verbose => 0 } );

defined $opt{indent}
    or $opt{indent} = $opt{tle} ? 0 : 4;

my $st = Astro::SpaceTrack->new(
    map { defined $opt{$_} ? ( $_ => $opt{$_} ) : () }
    qw{ identity username password }
);

my @symbolic;
# CAVEAT CODER -- encapsulation violation in next line.
foreach my $status_code ( @{ $Astro::SpaceTrack::EXPORT_TAGS{status} } ) {
    my $value = Astro::SpaceTrack->$status_code();
    $symbolic[$value] = $opt{symbolic} ? $status_code : $value;
}

if ( defined $opt{kelso_url} ) {
    my $url = $opt{kelso_url};
    if ( -f $url ) {
	require URI::file;
	$url = URI::file->new_abs( $url )->as_string();
    }
    $st->set( url_iridium_status_kelso => $url );
}

my @admit_to = map { "-$_" } grep { $opt{$_} } qw{ symbolic tle };
push @admit_to, "-indent=$opt{indent}";

if ( $opt{tle} ) {

    # Astro::Coord::ECI::TLE format

    my ( $resp, $data ) = $st->iridium_status(
	{ raw	=> 0 },
	'kelso',
    );

    $resp->is_success()
	or die "Failed to retrieve Iridium status: ", $resp->status_line();

    my_print( <<"EOD" );
# All Iridium Classic satellites.
#
# Generated by Astro::SpaceTrack tools/all_iridium_classic @admit_to
# on @{[ scalar gmtime ]} GMT

%status = (
EOD

    my @summary;

    foreach my $body ( @{ $data } ) {
	$summary[$body->[4]]++;
	my_print( <<"EOD" );
    '$body->[0]'	=> {
	'class'	=> 'Astro::Coord::ECI::TLE::Iridium',
	'comment' => '$body->[3]',
	'id'	=> '$body->[0]',
	'name'	=> '$body->[1]',
	'status' => $symbolic[$body->[4]],
	'type'	=> 'iridium'
    },
EOD
    }

    my_print( ");\n\n# Summary:\n" );
    my $inx = 0;
    my @name = qw{ Operational Spare Tumbling Decayed };
    foreach my $count ( @summary ) {
	my_print(
	    sprintf "#%12s [%s]: %d\n", $name[$inx], $symbolic[$inx],
	    $count,
	);
	$inx++;
    }

} else {

    # Astro::SpaceTrack format

    my ( $resp, $data ) = $st->iridium_status(
	{ raw	=> 1 },
	'spacetrack',
    );

    $resp->is_success()
	or die "Failed to retrieve Iridium status: ", $resp->status_line();

    my_print( <<"EOD" );
# All Iridium Classic satellites. The order of the data is:
# OID, name, status string, comment, portable status.
#
# Generated by tools/all_iridium_classic @admit_to
# on @{[ scalar gmtime ]} GMT

my \@all_iridium_classic = (
EOD

    foreach my $body ( @{ $data } ) {
	$body->[1] =~ s/ ( [0-9]+ ) / $1 + 0 /smxe;
	my_print( <<"EOD" );
    [ $body->[0], '$body->[1]', '$body->[2]', '$body->[3]', $symbolic[$body->[4]] ],
EOD
    }

    my_print( ");\n" );
}

sub my_print {
    my $output = join '', @_;
    my $indent = ' ' x $opt{indent};
    $output =~ s/ ^ (?! $ ) /$indent/smxg;
    $output =~ s<^ ( (?: [ ]{8} )+ ) >
    < "\t" x ( length( $1 ) / 8 ) >smxge;
    print $output;
    return;
}

__END__

=head1 TITLE

all_iridium_classic - Dump raw Space Track status for original-design Iridium satellites.

=head1 SYNOPSIS

 all_iridium_classic -identity
 all_iridium_classic -username somebody -password censored
 all_iridium_classic -help
 all_iridium_classic -version

=head1 OPTIONS

=head2 -celestrak-url

This option is a synonym for L<-kelso-url|/-kelso-url>.

=head2 -help

This option displays the documentation for this script. The script then
exits.

=head2 -identity

If asserted, this Boolean option causes the
L<Astro::SpaceTrack|Astro::SpaceTrack> C<identity> attribute to be set,
which in turn causes the user's Space Track username and password to be
read from a (hopefully encrypted) identity file.

The default is C<-noidentity>.

=head2 -indent

 -indent 4

This option indents the generated code the given number of spaces. Tab
conversion on the indentation will be done before output.

The default is C<-indent 0> if L<-tle|/-tle> is asserted, or
C<-indent 4> if not.

=head2 -kelso-url

 -kelso-url ~/kelso.txt

This option specifies an alternate URL for T. S. Kelso's Iridium status
data. If an existing file is specified, it is turned into a C<file:>
URL. Otherwise the value must be one that
L<LWP::UserAgent|LWP::UserAgent> understands.

The default is the L<Astro::SpaceTrack|Astro::SpaceTrack> default
(q.v.).

=head2 -password

 -password censored

This option specifies the user's Space Track password. It overrides the
password from the identity file, if any.

=head2 -symbolic

If this Boolean option is true, the symbolic names of the portable
statuses are used; otherwise the values are used.

The default is C<-nosymbolic>.

=head2 -username

 -username somebody

This option specifies the user's Space Track username. It overrides the
username from the identity file, if any.

=head2 -version

This option displays the version of this script. The script then exits.

=head1 DETAILS

This Perl script does a raw query of Iridium status from Space Track,
formats the results as Perl code, and writes them to standard out. The
raw data are not supplimented from Celestrak, so the only statuses are
unknown or decayed.

The purpose of this is to generate a canned status table in
L<Astro::SpaceTrack|Astro::SpaceTrack>, since all the other sources
typically drop the satellite when it decays.

You need a Space Track username and password to use this script.

=head1 AUTHOR

Tom Wyant (wyant at cpan dot org)

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2017-2018 by Thomas R. Wyant, III

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl 5.10.0. For more details, see the full text
of the licenses in the directory LICENSES.

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.

=cut

# ex: set textwidth=72 :