package H1::ZTE;
use warnings;
use strict;

use Moose::Role;

requires 'connect';
requires 'parse';

use Net::Telnet;
use Data::Dump qw(dump);

use Moose::Util::TypeConstraints;
use Regexp::Common qw(net);

subtype IPAddr
=> as Str
=> where {/^$RE{net}{IPv4}$/}
=> message { 'invalid IP address'};

has 'ip'   => ( is => 'rw', isa => 'IPAddr' );

our $telnet;

sub telnet {
	my $self = shift;

	my $ip = $self->ip;

	return $telnet->{$ip} if exists $telnet->{$ip};

	warn "connect $ip";
	my $t = $self->connect( $ip );

	return $telnet->{$ip} = $t;
}

sub command_out {
	my ($self,$command) = @_;

	my $t = $self->telnet;

	warn "# $command\n";
	$t->print($command);

	my $out;
	while (1) {
		my($prematch, $match) = $t->waitfor('/(Press any key to continue \(Q to quit\)|#)/');
		$out .= $prematch;
		last if $match eq '#';
		$t->print('');
	}

	warn "## out = [$out]" if $ENV{DEBUG};

	return $out;
}

sub command {
	my ($self,$command) = @_;
	my $out  = $self->command_out( $command );
	my $hash = $self->parse( $out );

	warn "## ", $self->ip, " $command ",dump $hash;

	return $hash;
}

sub hash {
	my ($self,$port) = @_;

	my $ip   = $self->ip;
	$self->{port} = $port;

	warn "# hash $ip $port";

	our ( $row, $hash );

	sub copy {
		my @what = @_;
		@what = keys %$hash unless @what;
		foreach my $name (@what) {
			$row->{$name} = $hash->{$name};
		}
	}

	my $commands = $self->commands;
	foreach my $command ( keys %$commands ) {
		$hash = $self->command( sprintf($command, $port) );
		copy ref $commands->{$command} eq 'ARRAY' ? @{$commands->{$command}} : undef;
	}

	if ( $self->can('custom') ) {
		$hash = $self->custom( $port );
		copy keys %$hash;
	}

	warn "# row = ",dump $row if $ENV{DEBUG};

	$row = $self->fixup_row( $row ) if $self->can('fixup_row');

	return $row;

} # sub


sub logout {
	my $self = shift;
	my $ip = $self->ip;
	my $t = delete $telnet->{$ip};
	return unless $t;
#	die "no $ip telnet in ",dump($telnet) unless $t;

	warn "logout $ip";
	$t->print('logout');
	# FIXME removed but needed?
	#$t->waitfor('/:/');
	#$t->print('y');
	$t->close;

}

sub DESTROY {
	my $self = shift;
#	warn "# DESTROY telnet = ",dump( keys %$telnet );
	$self->logout($_) foreach keys %$telnet;
}

1;

