use utf8;
use warnings; no warnings "redefine";
use strict;

use Dbase::Globals qw(content get_person name_kunde unterkunden);
use Dbase::Help qw(DoFn DoSelect in_list quote qquote);
use Loader qw( add_kunde_hardware
  edit_hardware
  hinweis_auf_kundebunt
  line_in list_hardwares log_view
  select_suche
  valid_kunde );
use Fehler qw(problem report_fehler);

# $flags & 1 => nicht zu edit_hardware() springen, sondern ID zurückliefern

my $ip_suche = sub {
	my ( $column, $sql, $fqdn, $mode ) = @_;
	my $sql_like;
	if ( $mode eq '-' ) {
		return problem("Suche mit '-' nur ohne Text") if length $fqdn;
		$sql_like = 'IS NULL';
	}
	elsif ( $mode eq '?' ) {
		$fqdn = "%$fqdn" unless $fqdn =~ /^%/;
		$fqdn .= '%' unless $fqdn =~ /%$/;
	}
	my @ids;
	$sql_like = 'LIKE ' . qquote($fqdn) unless $sql_like;
	DoSelect { push @ids, @_ } $sql . <<_;
	WHERE  ipkunde.name $sql_like
	   AND ( ipkunde.ende IS NULL OR ipkunde.ende >= UNIX_TIMESTAMP(NOW()) )
_
	unless (@ids) { 'NULL' }
	else          { in_list( "hardware.$column", '', @ids ) }
};

my %suche = (
	c  => 'console',
        e  => sub {
		my ($eigentuemer) = @_;
		my $e = get_person($eigentuemer)
		  or return problem qq(Unbekannter Eigentümer "$eigentuemer".);
		"hardware.eigentuemer = $e";
	},
	i  => 'info',
	id => 'hardware_id',
	ip => sub {
		$ip_suche->( ip => <<'_', @_ );
	SELECT id
	FROM   ipkunde
_
	},
	IP => sub {
		$ip_suche->( id => <<'_', @_ );
	SELECT hardware_ip.hardware
	FROM   hardware_ip
	JOIN   ipkunde ON ipkunde.id = hardware_ip.ip
_
	},
	iv => 'ivnr',
	n  => 'name',
	sn => 'seriennr',
	st => sub {
		my($standort) = @_;
		my $st = get_person($standort) or return problem qq(Unbekannter Standort "$standort".);
		my @ids;
		DoSelect { push @ids, @_ } <<_;
	SELECT hardware.id
	FROM   hardware, rack, rz
	WHERE  hardware.rack = rack.id AND rack.rz = rz.id AND rz.standort = $st
_
		unless (@ids) { "hardware.standort = $st" }
		elsif ( @ids == 1 ) {
			"( hardware.standort = $st OR hardware.id = @ids )"
		}
		else {
			"( hardware.standort = $st OR hardware.id IN (${\ join ',', @ids }) )";
		}
	},
	t  => 'ktarif',
);

sub edit_hardwares($;$$) {
	my ( $id, $kn, $flags ) = @_;
	$flags ||= 0;

	$kn = "Kunde $id:" . name_kunde($id) if $id && $kn eq '';

	hinweis_auf_kundebunt(<<'_');
Hardware-Objekte können auch bequem über die kundebunt-Web-Schnittstelle unter
<URL> verwaltet werden.
_

	aloop: while ( content( my $act = line_in "$kn Hardware >", 4 ) ) {
		( $act, my @select ) = split ' ', $act;
		for (@select) {
			$_ = select_suche($_, "hardware", %suche);
			next aloop unless defined $_;
		}
		if ( $act eq '?' ) {
			print <<'_';

l       alle aktiven Geräte mit Hardware-ID auflisten
ll      alle Geräte auflisten
L       alle (auch beendete) Geräte mit Hardware-ID auflisten
LL      alle (auch beendete) Geräte auflisten
lm      nur aktive Geräte mit eingetragener Management-IP auflisten
*l, *L, etc.: mit Unterkunden

Bei allen o.g. Funktionen können jeweils zusätzlich beliebig viele mit
Whitespace getrennte Suchargumente übergeben werden:

Folgende Suchoptionen sind möglich:
c   Console-Eintr.       e   Eigentümer           i   ZusatzInfo
id  Hardware-ID
ip  der eine primäre IP-Adresse zugeordnet ist, für die ein FQDN eingetragen ist
IP  der eine Interface-IP-Adresse zugeordnet ist, für die ein FQDN eingetragen ist
iv  Inventarnummer       n   Name                 sn  Seriennummer

Wenn man diese mit folgenden benutzt:
:... wird ... als SQL-Wildcard "..." zur Suche im Feld verwendet
?... werden Einträge angezeigt in desen Feld "..." vorkommt
-    werden Einträge deren feld leer (NULL) ist angezeigt

Zusätzliche Suchmöglichkeiten
st:...  nur Hardware mit Standort "..." anzeigen

Beispiele:
* "l n?Cisco st:nbg3" zeigt nur aktive Geräte mit Hardware-ID,
  in deren Name "Cisco" vorkommt und die am Standort "nbg3" stehen.
* "L iv:%" zeigt alle (also auch beendete) Geräte, bei denen eine
  Inventarnummer eingetragen ist (und die also mutmaßlich noris gehören).
* "L iv:" zeigt alle (also auch beendete) Geräte, bei denen keine
  Inventarnummer eingetragen ist
* "l i-" zeigt nur aktive Geräte die keinen Infotext haben 

Hinweis für Stoffel: Die Anführungszeichen bitte NICHT mit eingeben! :-)

_
			print <<'_' if $id;
a       hinzufügen

_
			next;
		}
		my %flgs = ( l=>0, ll=>2, L=>1, LL=>3, lm=>6 );
		my $flgs = join("|",keys %flgs);
		if ( $act =~ /^ (\*)? ($flgs) \z /ix ) {
			list_hardwares( ($1 && $id) ? [ unterkunden($id) ] : $id, $flgs{$2}, @select );
			next;
		}
		if ( $id && $act eq 'a' ) { add_kunde_hardware $id, $kn; next; }
		if ( $act eq 'H' ) { log_view $kn, 'hardware'; next; }
		if ( $act =~ /^\d+$/ ) {
			if ( DoFn "SELECT 1 FROM hardware WHERE id = $act" ) {
				return $act if $flags & 1;
				edit_hardware $act, $kn, $id;
			}
			else {
				print "Hardwarekomponente #$act nicht gefunden.\n";
			}
			next;
		}
		my $qact = qquote $act;
		return '-' if $act eq '-' && $flags & 1;
		if (
			defined(
				my $hardware = DoFn("SELECT id FROM hardware WHERE hardware_id = $qact")                                  ||
				        $id && DoFn("SELECT id FROM hardware WHERE name = $qact AND kunde = $id ORDER BY id LIMIT 1")     ||
				        $id && DoFn("SELECT id FROM hardware WHERE seriennr = $qact AND kunde = $id ORDER BY id LIMIT 1") ||
				               DoFn("SELECT id FROM hardware WHERE name = $qact ORDER BY kunde, id LIMIT 1")              ||
				               DoFn("SELECT id FROM hardware WHERE seriennr = $qact ORDER BY kunde, id LIMIT 1")          ||
				               DoFn(<<_)
	SELECT hardware.id
	FROM   hardware, ipkunde
	WHERE  hardware.ip  = ipkunde.id
	   AND ipkunde.name = $qact
	   AND ( ipkunde.ende IS NULL OR 
	         ipkunde.ende >= UNIX_TIMESTAMP(NOW())    )
_
			)
		  )
		{
			return $hardware if $flags & 1;
			edit_hardware $hardware, $kn, $id;
			next;
		}
		print "Aktion '$act' kenne ich nicht. Liste mit '?'.\n";
		next;
		fehler: report_fehler(4);
	}
	undef;
}

1;
