use utf8;
use warnings; no warnings "redefine";
use strict;
use Dbase::Globals qw(
  flag_names
  get_descr
  info_descr
  ipinfo
  mpersinfo
  name_kunde
  timerange
);
use Dbase::Help qw(DoFn DoSelect isotime DoTime);
use Fehler qw(problem);
use Loader qw(line_printer print_adresse);
use Dbase::IP;

my $sub_hw;
$sub_hw = sub {
	my($id,$flags,$prefix) = @_;
	$prefix .= '>';
	DoSelect {
		my($id, $name, $hardware_id) = @_;
		printf $Db::pr_fh "%-12s: %s\n", $prefix.'eingebaut',
		                  "#$id:$name" . ( defined $hardware_id && " [$hardware_id]");
		$sub_hw->($id, $flags, $prefix);
	} <<_;
	SELECT   id, name, hardware_id
	FROM     hardware
	WHERE    enthalten_in = $id  ${\( ($flags & 1) ? '' : "
	     AND ( ende IS NULL OR ende >= UNIX_TIMESTAMP(NOW()) )" )}
	ORDER BY name, hardware_id
_
};

# Flagbits:
# 1: auch beendete Wartungsverträge anzeigen
# 2: auch URL für Landkarte anzeigen
# 4: nur Messverbraucher anzeigen die das acct flag haben

sub list_hardware($;$) {
	my ( $idi, $flags ) = @_;
	$flags = 0 unless defined $flags;
	line_printer;

	my ( $timestamp, $kunde, $eigentuemer, $verantwortlich, $name, $typ, $klasse, $hardware_id, $ivnr, $seriennr, $enthalten_in, $standort, $lieferant, $status, $hardwareflags, $ip, $console, $info, $beginn, $ende, $rack, $unterste_he, $he, $ktarif )
	  = DoFn <<_
	SELECT    hardware.timestamp,
	          hardware.kunde,
	          hardware.eigentuemer,
	          hardware.verantwortlich,
	          hardware.name,
	          hardware.typ,
	          hardware.klasse,
	          hardware.hardware_id,
	          hardware.ivnr,
	          hardware.seriennr,
	          hardware.enthalten_in,
	          hardware.standort,
	          hardware.lieferant,
	          hardware.status,
		  hardware.flags,
	          hardware.ip,
	          hardware.console,
	          hardware.info,
	          hardware.beginn,
	          hardware.ende,
	          hardware.rack,
	          hardware.unterste_he,
	          hardware.he,
	          hardware.ktarif
	FROM      hardware
	WHERE     hardware.id = $idi
_
	  or return problem "Hardware #$idi nicht gefunden.";
	print $Db::pr_fh "ID          : $idi\n";
	print $Db::pr_fh 'Timestamp   : ' . isotime($timestamp) . "\n";
	print $Db::pr_fh "Kunde       : #$kunde:" . name_kunde($kunde) . "\n"
	  if $kunde;
	print $Db::pr_fh "Eigentümer  : #$eigentuemer:"
	  . mpersinfo($eigentuemer) . "\n"
	  if $eigentuemer;
	print $Db::pr_fh "Verantwortl.: #$verantwortlich:"
	  . mpersinfo($verantwortlich) . "\n"
	  if $verantwortlich;
	print $Db::pr_fh "Name        : $name\n"     if defined $name;
	if ( defined $typ ) {
		my $info = info_descr hardware_typ => $typ;
		print $Db::pr_fh "Typ         : " . get_descr( hardware_typ => $typ ) . ( defined $info && " ($info)" ) . "\n"
	}
	if ( defined $klasse ) {
		my $info = info_descr hardware_klasse => $klasse;
		print $Db::pr_fh "Klasse      : " . get_descr( hardware_klasse => $klasse ) . ( defined $info && " ($info)" ) . "\n"
	}
	if ( defined $ktarif ) {
        my ( $tarifname, $dienst ) = DoFn <<_;
SELECT tarifname.name, dienst.name
  FROM tarifname JOIN tarifkunde ON tarifname.id = tarifkunde.tarifname
    JOIN dienst ON tarifkunde.dienst = dienst.id
 WHERE tarifkunde.id = $ktarif
_
		print $Db::pr_fh "Tarif       : #$ktarif:$tarifname/$dienst\n";
	}
	print $Db::pr_fh "Hardware-ID : $hardware_id\n" if defined $hardware_id;
	print $Db::pr_fh "InventarNr  : $ivnr\n" if defined $ivnr;
	print $Db::pr_fh "SerienNummer: $seriennr\n" if defined $seriennr;
	if ( defined $status ) {
		my $info = info_descr hardware_status => $status;
		print $Db::pr_fh "Status      : " . get_descr( hardware_status => $status ) . ( defined $info && " ($info)" ) . "\n"
	}
	{
		my %seen;
		while ( defined $enthalten_in ) {
			( my $_name, my $_hardware_id, $standort, $rack, $unterste_he, my $_enthalten_in ) = DoFn <<_;
	SELECT name, hardware_id, standort, rack, unterste_he, enthalten_in
	FROM   hardware
	WHERE  id = $enthalten_in
_
			print $Db::pr_fh "enthalten in: #$enthalten_in:$_name"
			                 . ( defined $_hardware_id && " [#$_hardware_id]" )
			                 . "\n";
			last unless defined( $enthalten_in = $_enthalten_in );
			return problem 'Hardware ist gegenseitig ineinander eingebaut!?'
			  if $seen{$enthalten_in}++;
		}
	}
	if ( defined $rack ) {
		($standort, my @einbauort) = DoFn(<<_) or return problem("Rack #$rack nicht gefunden.");
	SELECT rz.standort, rz.name, rack.name
	FROM   rack, rz
	WHERE  rack.id = $rack AND rack.rz = rz.id
_
		print $Db::pr_fh 'Einbauort   : ' . join( ' / ', @einbauort ) . "\n";
	}

	DoSelect {
		my ($ms_id, $ms_name) = @_;
		my ($rack_name, $rz_name) = DoFn <<_;
SELECT rack.name, rz.name
  FROM hardware JOIN rack ON hardware.rack = rack.id
   JOIN rz ON rz.id = rack.rz
 WHERE hardware.id = $idi
_

		my @ms_text;
		push @ms_text, $rz_name   if $rz_name;
		push @ms_text, $rack_name if $rack_name;
		push @ms_text, $ms_name;
		my $text = join '/', @ms_text;

		print $Db::pr_fh "Messstelle  : #$ms_id:$text\n";
    } <<_1 . ( $flags & 4 ? <<_2 : '' );
SELECT mess_stelle.id, mess_stelle.name
  FROM mess_stelle JOIN mess_verbraucher ON mess_stelle.id = mess_verbraucher.mess_stelle
 WHERE mess_verbraucher.hardware = $idi
   AND ( mess_stelle.ende     IS NULL OR mess_stelle.ende     >= UNIX_TIMESTAMP(NOW()) )
   AND ( mess_verbraucher.ende IS NULL OR mess_verbraucher.ende >= UNIX_TIMESTAMP(NOW()) )
_1
   AND mess_verbraucher.acct = 'j'
_2

	# HE gesondert anzeigen wg. diff.hardware, vgl. RT#245519:
	print $Db::pr_fh 'HE          : ' . ( defined $unterste_he && $unterste_he ) . ( defined $he && "+$he" ) . "\n"
		if defined $unterste_he || defined $he;
	if ( defined $standort ) {
		print $Db::pr_fh "Standort    : #$standort:"
		  . mpersinfo($standort) . "\n";
		my $adr = DoFn <<_;
			SELECT adresse
			FROM   person
			WHERE  id = $standort
_
		if(defined $adr) {
			( $adr, my $url ) = print_adresse($adr);
			$adr =~ s/\n/\n              /g;
			print $Db::pr_fh "              $adr\n";

			# Feldname darf nicht eingerückt sein wegen diff.hardware:
			print $Db::pr_fh "->Landkarte : $url\n" if $flags & 2;
		}
	}
	if ( defined $lieferant ) {
		my $info = info_descr lieferant => $lieferant;
		print $Db::pr_fh 'Lieferant   : ' . get_descr( lieferant => $lieferant ) . ( defined $info && " ($info)") . "\n";
	}
	print $Db::pr_fh 'Primäre IP  : ' . ipinfo($ip) . "\n" if defined $ip;

	DoSelect { print $Db::pr_fh 'Interface-IP: ' . ipinfo(@_) ."\n" } <<_;
	SELECT   hardware_ip.ip,
	         ipkunde.ip6, ipkunde.bits, ipkunde.name, ipkunde.ende
	FROM     hardware_ip, ipkunde
	WHERE    hardware_ip.hardware = $idi
	     AND hardware_ip.ip = ipkunde.id
	ORDER BY ipkunde.ip6, ipkunde.ende
_
	print $Db::pr_fh "Console     : $console\n" if defined $console;
	print $Db::pr_fh "ZusatzInfo  : $info\n" if defined $info;
	print $Db::pr_fh 'Beginn      : ' . isotime($beginn) . "\n" if $beginn;
	print $Db::pr_fh 'Ende        : ' . isotime($ende) . "\n"   if $ende;
	print $Db::pr_fh 'Flags       : ' . flag_names( $hardwareflags, 'hardwareflags' ) . "\n";

	DoSelect {
		my ( $id, $leitung_kunde, $name ) = @_;
		print $Db::pr_fh "Leitungsende: #$id:$name"
		  . ( $leitung_kunde != $kunde
			  && " (Kunde #$leitung_kunde:" . name_kunde($leitung_kunde) . ')' )
		  . "\n";
	}
	<<_;
	SELECT   id, kunde, name
	FROM     leitung
	WHERE    $idi IN (a_hardware, b_hardware)
	     AND ( ende IS NULL OR ende >= UNIX_TIMESTAMP(NOW()) )
	ORDER BY kunde, name, id
_
	DoSelect {
		my($id, $wartungsvertrag, $beginn, $ende) = @_;
		print $Db::pr_fh "WartungsV.  : #$id:$wartungsvertrag ".timerange($beginn,$ende)."\n";
	} <<_;
	SELECT   wartungsvertrag_hardware.id,
	         wartungsvertrag.name,
	         wartungsvertrag_hardware.beginn,
	         wartungsvertrag_hardware.ende
	FROM     wartungsvertrag_hardware, wartungsvertrag
	WHERE    wartungsvertrag_hardware.hardware        = $idi
	     AND wartungsvertrag_hardware.wartungsvertrag = wartungsvertrag.id
	${\( ($flags & 1) ? '' : "
	     AND ( wartungsvertrag_hardware.ende IS NULL                  OR
	           wartungsvertrag_hardware.ende >= UNIX_TIMESTAMP(NOW()) )" )}
	ORDER BY wartungsvertrag_hardware.beginn
_
	$sub_hw->($idi,$flags);
}

1;
