#===========================================================================

package Sitescooper::UserAgent;
use LWP::UserAgent;

BEGIN {
  @ISA = qw(LWP::UserAgent);

  @Sitescooper::UserAgent::PasswdMask =
  	unpack ("c*", "Ish0ulDReallY#BeDoING|05th1S>wiTh".
			"5omEThInG+STr0NgeR1kNoW}iKNOw!~");
  %Sitescooper::UserAgent::outed_already_set_warn = ();
}

sub new {
  my($class) = @_;
  my $self = new LWP::UserAgent;

  $self->{last_redir} = undef;

  $self = bless $self, $class;
  $self;
}

sub get_basic_credentials {
  my ($self, $realm, $uri, $proxy) = @_;

  $Sitescooper::UserAgent::last_auth_realm = $realm;

  if (defined $site_logins{$realm} && defined $site_passes{$realm}) {
    if (!defined $Sitescooper::UserAgent::outed_already_set_warn{$realm}) {
      &Scoop::verbose ("(using already-set password for $uri $realm)");
      $Sitescooper::UserAgent::outed_already_set_warn{$realm} = 1;
    }

  } else {
    warn ("Need a password to access $realm ($uri).\n");
    if ($Scoop::cgimode || !-t) { return undef; }

    print STDERR ("Username: ");
    my $user = <STDIN>; chop $user;

    print STDERR ("Password: ");
    (&Scoop::MyOS eq 'UNIX') and system ("stty -echo");
    my $pass = <STDIN>; chop $pass;
    (&Scoop::MyOS eq 'UNIX') and system ("stty echo"); print STDERR "\n";

    $site_logins{$realm} = $user;
    $site_passes{$realm} = $pass;
  }

  ($site_logins{$realm}, $site_passes{$realm});
}

sub load_logins {
  if (defined %site_logins) { return %site_logins; }

  %site_logins = ();
  %site_passes = ();
  open (IN, '< '.$CF::user_tmpdir.$CF::slash.'site_logins') or return undef;

  #$site_logins{'tst'} = $site_passes{'tst'} = "jmason"; &save_logins;

  while (<IN>) {
    s/[\r\n]+$//g;
    my ($ver, $user, $pass, $realm) = split (/###/);
    if (defined $realm && $ver+0 == 0) {
      $site_logins{$realm} = $user;

      my @mask = @Sitescooper::UserAgent::PasswdMask;
      my @input = split (' ', $pass);
      my $pass_open = '';
      my $i = 0;

      foreach $_ (@input) {
	my $ch = (($_ ^ $mask[$i++ % $#mask]) ^ 0xaa);
	last if ($ch == 0);
	$pass_open .= sprintf ("%c", $ch);
      }

      $site_passes{$realm} = $pass_open;
    }
  }
  close IN;

  #print "[", $site_logins{'tst'}, "][", $site_passes{'tst'}, "]\n"; exit;
}

sub save_logins {
  if (!defined %site_logins) { return; }
  my $towrite = '';

  foreach $realm (sort keys %site_logins) {
    next unless (defined $site_passes{$realm} && defined $site_logins{$realm});

    my @mask = @Sitescooper::UserAgent::PasswdMask;
    my @input = (unpack ("c*", $site_passes{$realm}));
    my $pass_disguised = '';
    my $i = 0;

    foreach $_ (@input) {
      $pass_disguised .= (($_ ^ 0xaa) ^ $mask[$i++ % $#mask]) . " ";
    }
    while ($i < int(($#input / 16) + 1) * 16) {
      $pass_disguised .= ((0 ^ 0xaa) ^ $mask[$i++ % $#mask]) . " ";
    }
    chop $pass_disguised;

    $towrite .= "0###". $site_logins{$realm}. "###". $pass_disguised.
    		"###". $realm. "\n";
  }

  # again, all at once to minimise contention
  open (OUT, '> '.$CF::user_tmpdir.$CF::slash.'site_logins') or
  	(warn ("failed to write to site_logins file!\n"), return);
  print OUT $towrite;
  close OUT or warn ("failed to write to site_logins file!\n");
}

sub redirect_ok {
  my ($self, $req) = @_;

  &Scoop::verbose ("Redirected to: ".$req->uri->as_string);
  $self->note_redirect ($req->uri->as_string);
}

sub note_redirect {
  my ($self, $uri) = @_;
  $self->{last_redir} = $uri;
}

sub clear_redirect {
  my ($self) = @_;
  $self->{last_redir} = undef;
}

sub get_last_redirect {
  my ($self) = @_;
  $self->{last_redir};
}

sub redirect_occurred {
  my ($self) = @_;
  (defined $self->{last_redir});
}

1;

