#!/usr/bin/perl

BEGIN
{
    do "<path_to_conf_file>/OpenSRS.conf";

    # when running against live system, this must go through batch pool, rather
    # than the normal one

    $OPENSRS{ REMOTE_HOST } = "horizon.opensrs.net";	# TEST
#    $OPENSRS{ REMOTE_HOST } = "batch.opensrs.net";	# LIVE
}

use strict;
use lib $PATH_LIB;

use OpenSRS::XML_Client;
use Getopt::Long;

my ( $lock, $unlock, $infile, $csvfile );

GetOptions(
    "lock"	=> \$lock,
    "unlock"	=> \$unlock,
    "infile=s"	=> \$infile,
    "csvfile=s"	=> \$csvfile,
) or usage();

if ( not $lock xor $unlock ) {
    usage( "One of --lock or --unlock must be specified" );
}
my $lock_state = $lock ? 1 : 0;

if ( $infile and $csvfile ) {
    usage( "Only one of --infile and --csvfile can be specified");
}

my @domain_list = get_domain_list();
if ( not scalar @domain_list ) {
    usage( "No domains specified" );
}

my $XML_Client = OpenSRS::XML_Client->new( %OPENSRS );
$XML_Client->login;

open GOOD, ">logfile.good" or die "Can't open logfile.good for writing: $!";
open BAD, ">logfile.bad" or die "Can't open logfile.bad for writing: $!";
open SKIP, ">logfile.skip" or die "Can't open logfile.skip for writing: $!";

foreach my $fh ( \*GOOD, \*BAD, \*SKIP ) {
    my $oldfh = select $fh;
    $| = 1;
    select $oldfh;
}

foreach my $domain ( @domain_list ) {
    my $resp = $XML_Client->send_cmd(
	{
	    action	=> 'modify',
	    object	=> 'domain',
	    attributes	=> {
		data	    => 'status',
		domain_name => $domain,
		lock_state  => $lock_state,
	    },
	}
    );

    print "$domain: $resp->{ response_text }\n";

    if ( not $resp->{ is_success } ) {
	if ( $resp->{ response_code } == 450 ) {
	    # tld doesn't support locking, or status can't be updated
	    print SKIP "$domain: $resp->{ response_text }\n";
	} else {
	    # domain info not found, or invalid request
	    print BAD "$domain: $resp->{ response_text }\n";
	}
    } else {
	print GOOD "$domain: $resp->{ response_text }\n";
    }

    sleep 1;
}

$XML_Client->logout;

print "\nCompleted\n";

sub get_domain_list {
    my $fh;

    my $file = $infile || $csvfile || undef;

    if ( defined $file ) {
	open $fh, $file or usage( "Can't open $file for reading: $!" );
    } else {
	$fh = \*STDIN;
    };

    my @domain_list = <$fh>;

    # for csv-files, a bit of mangling is required.
    if ( defined $csvfile ) {
	# the first item in list is a field specifier.  Ignore it.
	shift @domain_list;

	# for the remainder of the file, the domain name is the 3rd field.
	@domain_list = map { (split /,/)[2] } @domain_list;
    }

    @domain_list =
	map { s/(^\s+)|(\s+$)//g; /^(\S+)/; $1 }
	grep { /\S/ }
	@domain_list;

    return @domain_list;
}

sub usage {
    my $message = shift;

    print <<EOF;
$message

Usage:
  $0 <--lock|--unlock> [--infile=<filename>|--csvfile=<filename>]

where:
    - one of --lock or --unlock must be specified.  Domain status will be set
      to this state.
    - if --infile is specified, file given should contain a list of
      domains to lock/unlock, one per line.
    - if --csvfile is specified, the file given should contain a CSV format
      list of domains, as supplied through RWI 'Search domains->Results to
      File'.
    - if neither --infile nor --csvfile are specified, the domain list will be
      accepted on standard input, and should consist of only a single domain
      per line

the following logfiles will be created
    logfile.good
	list of domains for which lock status successfully updated
    logfile.bad
	list of domains for which lock status could not be set due to internal
	problem (usually bad command, or domain not found)
    logfile.skip
	list of domains for which the lock status could not be set due to
	non-error condition (usually if the domain is with another reseller,
	TLD does not support domain locking, or the domain is locked at the
	registry level)
EOF

    exit;
}
