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
  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 ) = @_;
	if ( $mode eq '?' ) {
		$fqdn = "%$fqdn" unless $fqdn =~ /^%/;
		$fqdn .= '%' unless $fqdn =~ /%$/;
	}
	my @ids;
	DoSelect { push @ids, @_ } $sql . <<_;
	WHERE  ipkunde.name LIKE ${\ qquote($fqdn) }
	   AND ( ipkunde.ende IS NULL OR ipkunde.ende >= UNIX_TIMESTAMP(NOW()) )
_
	unless (@ids) { 'NULL' }
	else          { in_list( "hardware.$column", '', @ids ) }
};

my %suche = (
	n  => 'name',
	c  => 'console',
	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',
	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 }) )";
		}
	}
);

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) {
			unless ( s/^(${\ join '|', keys %suche })([?:])\s*//o ) {
				problem "Unbekannte Suchmethode: $_";
				next aloop;
			}
			elsif ( ref $suche{$1} ) {
				defined( $_ = $suche{$1}->($_,$2) ) or next aloop;
			}
			else {
				if ( $2 eq '?' ) {
					$_ = "%$_" unless /^%/;
					$_ .= '%'  unless /%$/;
				}
				$_ = "hardware.$suche{$1} " . ( length() ? "LIKE ${\ qquote($_) }" : 'IS NULL' );
			}
		}
		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:

n:...	nur Hardware anzeigen, deren Name           zu SQL-Wildcard "..." passt
c:...   nur Hardware anzeigen, deren Console-Eintr. zu SQL-Wildcard "..." passt
id:...  nur Hardware anzeigen, deren Hardware-ID    zu SQL-Wildcard "..." passt
ip:...  nur Hardware anzeigen, der eine primäre IP-Adresse zugeordnet ist,
        für die ein FQDN eingetragen ist, der zur SQL-Wildcard "..." passt
IP:...  nur Hardware anzeigen, der eine Interface-IP-Adresse zugeordnet ist,
        für die ein FQDN eingetragen ist, der zur SQL-Wildcard "..." passt
iv:...  nur Hardware anzeigen, deren Inventarnummer zu SQL-Wildcard "..." passt
sn:...  nur Hardware anzeigen, deren Seriennummer   zu SQL-Wildcard "..." passt
st:...  nur Hardware mit Standort "..." anzeigen

n?...   nur Hardware anzeigen, in deren Name           "..." vorkommt
c?...   nur Hardware anzeigen, in deren Console-Eintr. "..." vorkommt
id?...  nur Hardware anzeigen, in deren Hardware-ID    "..." vorkommt
ip?...  nur Hardware anzeigen, der eine primäre IP-Adresse zugeordnet ist,
        für die ein FQDN eingetragen ist, in dem "..." vorkommt"
IP?...  nur Hardware anzeigen, der eine Interface-IP-Adresse zugeordnet ist,
        für die ein FQDN eingetragen ist, in dem "..." vorkommt"
iv?...  nur Hardware anzeigen, in deren Inventarnummer "..." vorkommt
sn?...  nur Hardware anzeigen, in deren Seriennummer   "..." vorkommt

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

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;
