#!/usr/local/bin/tclsh8.6

#
# List networks
#
# Called by: admin
#
# Parameters (form or url):
#   - selection criteria:
#	- addr = cidr of network
#	- org = list of organization ids
#	- comm = list of community ids
#   - sort criteria
#	- sort1 = addr4|addr6|name|organization|community|location|comment
#	- sort2 = addr4|addr6|name|organization|community|location|comment
#   - output format:
#	- dolist, doprint or docsv
#
# History
#   2002/10/24 : pda      : design
#   2003/05/13 : pda/jean : use auth base
#   2004/01/14 : pda/jean : add IPv6
#   2005/09/28 : pda/jean/lauce : allow access for non administrators
#   2010/12/12 : pda      : i18n
#   2010/12/26 : pda      : use cgi-dispatch
#

#
# Template pages used by this script
#

set conf(page-sel)	lnet.html
set conf(page-html)	listof.html
set conf(page-latex)	listof.tex

#
# Next actions
# 

set conf(next)		"lnet"

#
# tabular specification for result
# Colonnes :
#	- Description
#	- Location
#	- IPv4 address
#	- IPv6 address
#	- Organization
#	- Community
#	- Comment
#

set conf(tableau) {
    global {
	chars {10 normal}
	columns {20 20 10 10 10 10 20}
	botbar {yes}
	align {left}
	latex {
	    linewidth { 258 }
	}
    }
    pattern Title {
	title {yes}
	topbar {yes}
	chars {10 bold}
	align {center}
	vbar {yes}
	column { }
	vbar {yes}
	column { }
	vbar {yes}
	column { }
	vbar {yes}
	column { }
	vbar {yes}
	column { }
	vbar {yes}
	column { }
	vbar {yes}
	column { }
	vbar {yes}
    }
    pattern Normal {
	vbar {yes}
	column { }
	vbar {yes}
	column { }
	vbar {yes}
	column { }
	vbar {yes}
	column { }
	vbar {yes}
	column { }
	vbar {yes}
	column { }
	vbar {yes}
	column { }
	vbar {yes}
    }
}

#
# Netmagis general library
#

source /usr/local/lib/netmagis/libnetmagis.tcl

# ::webapp::cgidebug ; exit

##############################################################################
# Utility functions
##############################################################################

proc sort-crit {key} {
    switch -- $key {
	name		{ set sql "n.name ASC" ; set txt [mc "Name"] }
	organization	{ set sql "org ASC" ; set txt [mc "Organization"] }
	community	{ set sql "comm ASC" ; set txt [mc "Community"] }
	location	{ set sql "n.location ASC" ; set txt [mc "Location"] }
	comment		{ set sql "n.comment ASC" ; set txt [mc "Description" }
	addr6		{ set sql "n.addr6 ASC" ; set txt [mc "IPv6 address"] }
	addr4		-
	default		{ set sql "n.addr4 ASC" ; set txt [mc "IPv4 address"] }
    }
    return [list $sql $txt]
}

##############################################################################
# Output list
##############################################################################

# format : html, csv or latex

proc output {dbfd _ftab format} {
    global conf
    upvar $_ftab ftab

    #
    # Argument analysis
    #

    # sort criteria
    lassign [sort-crit [lindex $ftab(sort1) 0]] sqlsort1 txtsort1
    lassign [sort-crit [lindex $ftab(sort2) 0]] sqlsort2 txtsort2

    #
    # Selection criteria
    #

    set selection ""
    set txtsel {}

    # cidr
    set cidr [string trim [lindex $ftab(addr) 0]]
    if {$cidr ne ""} then {
	set msg [check-ip-syntax $dbfd $cidr "cidr"]
	if {$msg ne ""} then {
	    d error $msg
	}
	append selection "AND (n.addr4 <<= '$cidr' OR n.addr6 <<= '$cidr')"
	lappend txtsel [mc "CIDR matches '%s'" $cidr]
    }

    # organization list
    if {[info exists ftab(organization)]} then {
	set lsqlorg {}
	set ltxtorg {}
	pg_select $dbfd "SELECT * FROM dns.organization" tab {
	    set to($tab(idorg)) $tab(name)
	}
	foreach idorg $ftab(organization) {
	    if {! [info exists to($idorg)]} then {
		d error [mc "Organization id '%s' not found" $idorg]
	    }
	    lappend lsqlorg "n.idorg = $idorg"
	    lappend ltxtorg "$to($idorg)"
	}
	if {[llength $lsqlorg] > 0} then {
	    set l [join $lsqlorg " OR "]
	    append selection " AND ($l)"
	    set t [join $ltxtorg [mc " or "]]
	    lappend txtsel [mc "organization = %s" $t]
	}
    }

    # Community list
    if {[info exists ftab(community)]} then {
	set lsqlcomm {}
	pg_select $dbfd "SELECT * FROM dns.community" tab {
	    set tc($tab(idcomm)) $tab(name)
	}
	foreach idcomm $ftab(community) {
	    if {! [info exists tc($idcomm)]} then {
		d error [mc "Community id '%s' not found" $idcomm]
	    }
	    lappend lsqlcomm "n.idcomm = $idcomm"
	    lappend ltxtcomm "$tc($idcomm)"
	}
	if {[llength $lsqlcomm] > 0} then {
	    set l [join $lsqlcomm " OR "]
	    append selection " AND ($l)"
	    set t [join $ltxtcomm [mc " or "]]
	    lappend txtsel [mc "community = %s" $t]
	}
    }

    #
    # Display information
    #

    set lines {}
    lappend lines [list "Title" \
			[mc "Name"] \
			[mc "Location"] \
			[mc "IPv4"] \
			[mc "IPv6"] \
			[mc "Organization"] \
			[mc "Community"] \
			[mc "Description"] \
		    ]

    set sql "SELECT n.idnet,
		    n.name, n.location, n.addr4, n.addr6, 
		    o.name AS org, c.name AS comm, n.comment
		FROM dns.network n, dns.organization o, dns.community c
		WHERE n.idorg = o.idorg AND n.idcomm = c.idcomm
			$selection
		ORDER BY $sqlsort1, $sqlsort2"
    set nnet 0
    pg_select $dbfd $sql tab {
	lappend lines [list Normal \
				$tab(name) \
				$tab(location) \
				$tab(addr4) \
				$tab(addr6) \
				$tab(org) \
				$tab(comm) \
				$tab(comment) \
			    ]
	incr nnet
    }

    set tableau [::arrgen::output $format $conf(tableau) $lines]

    #
    # End of script: output page and close database
    #

    set datefmt [dnsconfig get "datefmt"]
    set date  [clock format [clock seconds] -format $datefmt]
    set title [mc "networks"]
    switch -- $format  {
	html	{
	    set txt1 [mc "List of networks filtered by: "]
	    if {[llength $txtsel] == 0} then {
		append txt1 [mc " (no filter) "]
	    } else {
		set tmp ""
		foreach t $txtsel {
		    append tmp [::webapp::helem "li" $t]
		}
		append txt1 [::webapp::helem "ul" $tmp]
	    }
	    set txt2 [mc {and sorted by '%1$s' and by '%2$s'} $txtsort1 $txtsort2]
	    set txt3 [mc "%s selected network(s)." $nnet]
	    set txt "$txt1 $txt2: $txt3"

	    d result $conf(page-html) [list \
					[list %TITLE%	$title] \
					[list %TXT%	$txt] \
					[list %TABLEAU%	$tableau] \
					[list %DATE%	$date] \
				    ]
	}
	csv	{
	    ::webapp::send csv $tableau
	    d end
	}
	latex	{
	    set txt1 [mc "List of networks filtered by: "]
	    if {[llength $txtsel] == 0} then {
		append txt1 [mc " (no filter) "]
	    } else {
		set tmp "\\begin\{itemize\}"
		foreach t $txtsel {
		    append tmp "\\item $t\n"
		}
		append tmp "\\end\{itemize\}"
		append txt1 $tmp
	    }
	    set txt2 [mc {and sorted by '%1$s' and by '%2$s'} $txtsort1 $txtsort2]
	    set txt3 [mc "%s selected network(s)." $nnet]
	    set txt "$txt1 $txt2: $txt3"

	    d result $conf(page-latex) [list \
					[list %ORIENTATION%	"landscape"] \
					[list %TITLE%	$title] \
					[list %TXT%	$txt] \
					[list %TABLEAU%	$tableau] \
					[list %DATE%	$date] \
				    ]
	}
    }
}

##############################################################################
# Display selection page
##############################################################################

d cgi-register {
    dolist {}
    doprint {}
    docsv {}
} {
} {
    global conf

    #
    # Extract organization and community lists, and make listboxes
    #

    set lo [::pgsql::getcols $dbfd dns.organization "" "name ASC" {idorg name}]
    set h [llength $lo]
    set listorg [::webapp::form-menu "organization" $h 1 $lo {}]

    set lc [::pgsql::getcols $dbfd dns.community "" "name ASC" {idcomm name}]
    set h [llength $lo]
    set listcomm [::webapp::form-menu "community" $h 1 $lc {}]

    #
    # Sort criteria
    #

    set sortcrit [list \
			[list addr4		[mc "IPv4 address"]] \
			[list addr6		[mc "IPv6 address"]] \
			[list name		[mc "Name"]] \
			[list organization	[mc "Organization"]] \
			[list community		[mc "Community"]] \
			[list location		[mc "Location"]] \
			[list comment		[mc "Comment"]] \
		    ]
    set menu1 [::webapp::form-menu sort1 1 0 $sortcrit 0]
    set menu2 [::webapp::form-menu sort2 1 0 $sortcrit 1]

    #
    # End of script: output page and close database
    #

    d urlset "%URLFORM%" $conf(next) {}
    d result $conf(page-sel) [list \
				[list %LISTORG%   $listorg] \
				[list %LISTCOMM%  $listcomm] \
				[list %MENUSORT1% $menu1] \
				[list %MENUSORT2% $menu2] \
			    ]
}

##############################################################################
# Display list
##############################################################################

d cgi-register {dolist .+} {
    {addr		1 1}
    {organization	0 9999}
    {community		0 9999}
    {sort1		1 1}
    {sort2		1 1}
} {
    output $dbfd ftab "html"
}

##############################################################################
# Print list
##############################################################################

d cgi-register {doprint .+} {
    {addr		1 1}
    {organization	0 9999}
    {community		0 9999}
    {sort1		1 1}
    {sort2		1 1}
} {
    output $dbfd ftab "latex"
}

##############################################################################
# CSV list
##############################################################################

d cgi-register {docsv .+} {
    {addr		1 1}
    {organization	0 9999}
    {community		0 9999}
    {sort1		1 1}
    {sort2		1 1}
} {
    output $dbfd ftab "csv"
}

##############################################################################
# Main procedure
##############################################################################

d cgi-dispatch "dns" ""
