#!/usr/bin/perl -w
# Insert templates
# Richard Foley RFI perlbug@rfi.net
# $Id: bugtemplates,v 1.7 2002/01/25 16:12:59 richardf Exp $
#
use Perlbug::Test;
use strict;
use lib qw(../); 
use Data::Dumper;
use FileHandle;
use Getopt::Std; 
use Mail::Internet;
use Perlbug::Base;
use Sys::Hostname;
my $o_pb   = Perlbug::Base->new;
my $o_test = Perlbug::Test->new($o_pb);


=head1 NAME

bugtemplates - insert object templates

=head1 DESCRIPTION

Inserts <Perlbug::Object::Template>s on behalf of all/any objects into database.

Object type based on contents of B<Perlbug::Object::Object> table.

For this to be practical, each format type should have, in addition to default types for Flag and Mail objects, a distinct template for corresponding Bug, Group and User objects.  Application and Item defaults can use the _merge routine with no great loss (except beauty :-)

=head1 USAGE

	./bugtemplates -[dfFhmoqtux]

=head1 SYNOPSIS

Only insert ascii bug templates against user perlbug, richardf and mickey mouse

	./bugtemplates -f a -o bug -u perlbug:richardf:mm

Force insert of default html templates only

	./bugtemplates -f h -x default -F

=head1 SWITCHES

=over 4

=item d

debug level

=item f

format (a|h|H|i|L|...) default is all /\w+/

=item F

Force insert, even though comparable exists (will overwrite) in DB

=item h

help - perldoc $0

=item m

max number of inserts to process

=item o

object (bug|patch|user|...) or defaults for (mail|flag|...) - default is /\w+/

=item q

quiet

=item t

test - no inserts, just echo which would have been inserted

=item u

user:s who can use these templates - default is perlbug (list split by B<:>)

=item x

object / default (similar to B<f> and B<u>)

=cut

# ARGs
my %arg = (
	'd'	=> 0,   		# debug
	'f'	=> '^\w+$', 	# format 
	'F'	=> 0, 			# Force
	'h' => 0, 			# help
	'm'	=> 101, 		# max
	'o'	=> '^\w+$',		# object/s
	'q'	=> 0, 			# quiet
	't' => 0, 			# test 
	'u'	=> 'perlbug',	# user (relate) 
	'x'	=> '^\w+$',		# object/default
);
getopts('d:f:Fhi:m:o:qtu:x:', \%arg);
use vars(qw($d $h $f $F $m $o $q $t $u $x));
foreach my $switch (keys %arg) {
	no strict 'refs';
	$$switch = $arg{$switch};
}

if ($h) {
	exec "perldoc $0";
}

=back


=head1 TEMPLATES

Divided by format, default or object type, object key:

For an explanation of each format see L<Perlbug::Format>

	+ means the template is supplied here and will be B<merge()>'d

	- means it isn't (and will use the default B<_merge()> unless template provided)

  Formats: a A h H i I l L x X
  ============================
  APPLIC:  a A h H i I l L x X
  default  - - - - - - - - - -
  log      - - - - - - - - - -
  range    - - - - - - - - - -

  FLAG:    a A h H i I l L x X
  default  + + + + + + + + - -
  change   - - - - - - - - - - 
  fixed    - - - - - - - - - -
  osname   - - - - - - - - - -
  project  - - - - - - - - - -
  severity - - - - - - - - - -
  status   - - - - - - - - - -
  version  - - - - - - - - - -

  ITEM:    a A h H i I l L x X
  default  - - - - + + + + - -
  address  + + - - - - - - - -   
  group    + + + + - - + + - - 
  user     + + + + - - + - - - 

  MAIL:    a A h H i I l L x X
  default  + + + + + + + + - -
  bug      + + + + - - + + - -  
  child    - - - - - - - - - -
  message  - - - - - - - - - -
  note     - - - - - - - - - -
  parent   - - - - - - - - - -
  patch    - - - - - - - - - -
  test     - - - - - - - - - -

Note that B<H> is really the only place where a B<table> is necessary, see L<Perlbug::Interface::Web::start()> (and B<finish()>

=cut

my %TEMPLATES = (
	'A' => { 					# ASCII - long
		'default'	=> {		# DEFAULT A
			# 'application'	=>  # A
			'flag'	=> {		# A
				'description'	=> 'ASCII flag template', 
				'wrap'			=> '75',
				'repeat'		=> 1,
				'header'		=> "\n",
				'body'			=> q#
<{name}> 
<{key}>id: <{id4key}>  Created: <{created}>  Modified: <{created}>
Bug ids: <{bug_count}> <{bug_ids}>
#,
			},
			#'item'	=> {},		# A 
			'mail'	=> {		# A
				'description'	=> 'ASCII mail template', 
				'wrap'			=> '75',
				'repeat'		=> 1,
				'header'		=> "\n",
				'body'			=> q#
<{key}>id: <{id4key}>  Created: <{created}>  Modified: <{created}>
Subject: <{subject}>
Source:  <{sourceaddr}>

Bug ids: <{bug_count}> <{bug_ids}>

Header:   
<{header}>

Body:
<{body}>
#,
			},
		},
		'object'	=> {		# OBJECT A
			'address'	=> {	# A
				'description'	=> 'ASCII address template', 
				'repeat'		=> 1,
				'header'		=> "\n",
				'body'			=> q#
Address:   <{name}> 
Addressid: <{addressid}5>  Bug count: <{bug_count}>  ids: <{bug_ids}>
Created:   <{created}>  Modified: <{created}>
#,
			},
			'bug'	=> {		# A
				'description'	=> 'ASCII bug template', 
				'repeat'		=> 1,
				'header'		=> "\n",
				'body'			=> q#
Bug:      <{bugid}15>  
Subject:  <{subject}>
From:     <{sourceaddr}>
Created:  <{created}>  Modified: <{created}>

Status:   <{status_names}15 >  Severity: <{severity_names}>
OS names: <{osname_names}>
Group:    <{group_names}>
Version:  <{version_names}15>  Fixed in:  <{fixed_names}>

Message ids: <{message_count}5>  <{message_ids}>
Patch ids:   <{patch_count}  5>  <{patch_ids}>
Test ids:    <{test_count}   5>  <{test_ids}>
Note ids:    <{note_count}   5>  <{note_ids}>
Change ids:  <{change_count} 5>  <{change_names}>
Parent ids:  <{parent_count} 5>  <{parent_ids}>
Child ids:   <{child_count}  5>  <{child_ids}>
Address ids: <{address_count}5>  <{address_names}>
	
Header:   
<{header}>

Body:
<{body}>
#,
			},
			'group' => {		# A
				'description'	=> 'ascii group template', 
				'repeat'		=> 1,
				'header'		=> "\n",
				'body'			=> q#
Group:       <{name}>
Groupid:     <{groupid}> Created: <{created}>  Modified: <{created}>
Description: <{description}>
Address ids: <{address_count}5>  <{address_ids}>
User ids:    <{user_count}5   >  <{user_ids}>
Bug  ids:    <{bug_count} 5   >  <{bug_ids}>
#,
			},
			'user' => {			# A
				'description'	=> 'ascii user template', 
				'repeat'		=> 1,
				'header'		=> "\n",
				'body'			=> q#
Userid:     <{userid}15>  Name: <{name}>  Active: <{active}>
Created:    <{created}>  Modified: <{created}>
Address:    <{address}>
Match address: <{match_address}>
Password:   <{password}>
Groups:     <{group_count}   5> <{group_ids}>
Bug ids:    <{bug_count}     5> <{bug_ids}>
#,
			},
		},
	},	# end A
	'a'	=> {					# ascii - short
		'default'	=> {		# DEFAULT a
			#'application'	=> {},
			'flag'	=> {		# a
				'repeat'		=> 1,
				'header'		=> "\n",
				'body'			=> q#
<{key}>id <{id4key}>  
Created: <{created}>  Modified: <{created}>
Bug ids: <{bug_count}>
#,
			},
			#'item'	=> {},		# a
			'mail'	=> {		# a
				'repeat'		=> 1,
				'header'		=> "\n",
				'body'			=> q#
<{key}>id  <{id4key}>
Created: <{created}>  Modified: <{created}>
Subject: <{subject}>
Source:  <{sourceaddr}>
Bug ids: <{bug_count}>
#,
			},
		},
		'object'	=> {		# OBJECT a
			'address'	=> {	# a
				'repeat'		=> 1,
				'header'		=> "\n",
				'body'			=> q#

Address:   <{name}> 
Addressid: <{addressid}5>  Bug count: <{bug_count}>
Created:   <{created}>  Modified: <{created}>
#,
			},
			'bug'	=> {		# a
				'header'		=> "\n",
				'repeat'		=> 1,
				'body'			=> q#
Bug:      <{bugid}15>  
Subject:  <{subject}>
From:     <{sourceaddr}>
Created:  <{created}>  Modified: <{created}>

Status:   <{status_names}15 >  Severity: <{severity_names}>
OS names: <{osname_names}>
Group:    <{group_names}>
Version:  <{version_names}15>  Fixed in:  <{fixed_names}>

Message ids: <{message_count}5>  
Patch ids:   <{patch_count}  5> 
Test ids:    <{test_count}   5>
Note ids:    <{note_count}   5>
Change ids:  <{change_count} 5>
Parent ids:  <{parent_count} 5>
Child ids:   <{child_count}  5>
Address ids: <{address_count}5>
#,
			},
			'group' => {		# a
				'description'	=> 'ascii group template', 
				'repeat'		=> 1,
				'header'		=> "\n",
				'body'			=> q#
Groupid:     <{groupid}5      >  Name: <{name}>
Created:     <{created}>  Modified: <{created}>
Description: <{description}>
Address ids: <{address_count}5>  User ids: <{user_count}5   >
Bug ids:     <{bug_count} 5   > 
#,
			},
			'user' => {			# a
				'description'	=> 'ascii user template', 
				'repeat'		=> 1,
				'header'		=> "\n",
				'body'			=> q#
Userid:     <{userid}15>  Name: <{name}>  Active: <{active}>
Created:    <{created}>  Modified: <{created}>
Address:    <{address}>
Groups:     <{group_count}   5> <{group_names}>
Bug ids:    <{bug_count}     5> 
		#,
			},
		},
	},	# end a
	'H' => { 					# HTML - long
		'default'	=> {
			# 'application'	=>  # H
			'flag'	=> {
				'repeat'		=> 1,
				'header'		=> q#
<tr>
<td>&nbsp:</td><td><b><{key}> id</b></td><td><b>Bug ids</b></td>
<td><b>Created</b></td><td><b>Modified</b></td>
</tr>
#,
				'body'			=> q#
<tr>
<td> <{ifadmin}> <{select}> </{ifadmin}> &nbsp;</td>,
<td><{id4key}>: <{name}></td>
<td>Bug ids(<{bug_count}>) <{bug_names}></td>
<td>Created: <{created}></td>
<td>Modified: <{created}></td>
</tr>
<tr>
<{bug_ids}>
</tr>
<{ifadmin}>
<tr><td colspan=4><{options}></td></tr>
</{ifadmin}>
#,
			},
			# 'item'	=>  	# H rjsf
			'mail'	=> {		# H
				'description'	=> 'HTML mail template', 
				'repeat'		=> 1,
				'header'		=> q#
#,
				'footer'		=> q#
#,
				'body'		=> q#
<table border=1 width=100%>
<tr><td><b> <{ifadmin}> <{select}> </{ifadmin}> <{key}> id</b></td><td><{id4key}></td>
	<td><b>Created</b></td><td><{created}></td></tr>
<tr><td><b>Bugids</b>(<{bug_count}>)</td><td><{bug_ids}></td>
	<td><b>Modified</b></td><td><{modified}></td></tr>
<tr><td><b>Subject</b></td><td colspan=3><{subject}></td></tr>
<tr><td><b>Source</b></td><td colspan=3><{sourceaddr}></td></tr>
<tr><td colspan=4><{body}></td></tr>
<{ifadmin}>
<tr><td colspan=4><{options}></td></tr>
</{ifadmin}>
</table>
#,
			},
		},
		'object'	=> {
			'bug'		=> 	{ # H rjsf
				'description'	=> 'HTML mail template', 
				'repeat'		=> 1,
				'header'		=> q#
<table border=1 width=100%>
#,
				'footer'		=> q#
</table>
#,
				'body'		=> q#
<table border=1 width=100%>
<tr><td colspan=2><b> <{ifadmin}> <{select}> </{ifadmin}>
Bug id</b>: <{bugid}></td>
	<td><b>Change ids</b></td><td><{change_names}></td></tr>
<tr><td><b>Status</b></td><td><{status_names}></td>
	<td><b>Severity</b></td><td><{severity_names}></td></tr>
<tr><td><b>Created</b></td><td><{created}></td>
	<td><b>Modified</b></td><td><{modified}></td></tr>
<tr><td><b>Groups</b></td><td><{group_names}></td>
	<td><b>Osname</b></td><td><{osname_names}></td></tr>
<tr><td><b>Version</b></td><td><{version_names}></td>
	<td><b>Fixed in</b></td><td><{fixed_names}></td></tr>
<tr><td><b>Subject</b></td><td colspan=3><{subject}></td></tr>
<tr><td><b>Source</b></td><td colspan=3><{sourceaddr}></td></tr>
<tr><td><b>Admins</b>:</td><td colspan=3><{user_names}></td></tr>
<tr><td><b>Message ids</b>:</td><td><{message_ids}></td>
	<td><b>Note ids</b></td><td><{note_ids}></td></tr>
<tr><td><b>Patch ids</b>:</td><td><{patch_ids}></td>
	<td><b>Test ids</b></td><td><{test_ids}></td></tr>
<tr><td><b>Parent ids</b>:</td><td><{parent_ids}></td>
	<td><b>Child ids</b></td><td><{child_ids}></td></tr>
<{ifadmin}>
<tr><td colspan=4>
  <table><tr>
    <td><b>Note </b>:<br><{new_note}></td>
	<td><b>Patch</b>:<br><{new_patch}></td>
	<td><b>Test </b>:<br><{new_test}></td>
    </tr></table>
  </td></tr>
</{ifadmin}>
</table>
<table border=1>
<tr><td><{body}></td></tr>
<tr><td>&nbsp;</td></tr>
<{ifadmin}>
<tr><td colspan=4><{options}></td></tr>
</{ifadmin}>
</table>
#,
			},
			'group'	=> {		# H 
				'description'	=> 'HTML group template', 
				'repeat'		=> 1,
				'header'		=> q#
<table border=1 width=100%>
#,
				'footer'		=> q#
<tr><td colspan=4>&nbsp;</td></tr>
</table>
#,
				'body'		=> q#
<tr><td><b> <{ifadmin}> <{select}> </{ifadmin}>
Group id</b></td><td><{groupid}></td>
	<td><b>Created</b></td><td><{created}></td></tr>
<tr><td><b>Name</b></td><td><{name}></td>
	<td><b>Modified</b></td><td><{modified}></td></tr>
<tr><td><b>Description</b></td><td colspan=3><{description}></td></tr>
<tr><td><b>Bugids</b>(<{bug_count}>)</td><td><{bug_ids}></td>
	<td><b>Userids</b>(<{user_count}>)</td><td><{user_names}></td></tr>
<{ifadmin}>
<tr><td colspan=4><{options}></td></tr>
</{ifadmin}>
#,
			},
			'user'	=> {		# H
				'description'	=> 'HTML user template', 
				'repeat'		=> 1,
				'header'		=> qq#<table border=1 width=100%>\n#,
				'footer'		=> q#
<tr><td colspan=4>&nbsp;</td></tr>
</table>
#,
				'body'			=> q#
<tr><td><b> 
<{ifadmin}> <{select}> </{ifadmin}>
User id</b></td><td><{userid}></td>
	<td><b>Created</b></td><td><{created}></td></tr>
<tr><td><b>Name</b></td><td><{name}></td>
	<td><b>Modified</b></td><td><{modified}></td></tr>
<tr><td><b>Address</b></td><td><{address}></td>
	<td><b>Match addresss</b></td><td><{match_address}></td></tr>
<tr><td><b>Bug ids</b>(<{bug_count}>)</td><td><{bug_ids}></td>
	<td><b>Groups</b>(<{group_count}>)</td><td><{group_names}></td></tr>
<{ifadmin}>
<tr><td><b>Password</b></td><td><{password}></td>
	<td><b>Active</b></td><td><{active}></td></tr>
<tr><td colspan=4><{options}></td></tr>
</{ifadmin}>
#, 
			},
		},
	},	# end H 
	'h'	=> {					# html - short
		'default'	=> {		# DEFAULT h
			# 'application'	=>  # h
			'mail'	=> {		# h
				'description'	=> 'html mail template', 
				'header'		=> # '<tr><td colspan=15><hr></td></tr>',
					'<tr><td>'.join('</td><td>', (
					'<b>&nbsp;</b>',
					'<b><{key}>id</b>',
					'<b>Bugids</b>',
					'<b>Subject</b>',
					'<b>Source</b>',
					'<b>Created</b>',
					'<b>Modified</b>',
				))."</td></tr>\n",
				'repeat'		=> 10,
				'footer'		=> '',
				'body'			=> '<tr valign="top"><td>'.join('</td><td>', (
					'<{ifadmin}><{select}></{ifadmin}>&nbsp;',
					'<{id4key}>&nbsp;',
					'<{bug_ids}>&nbsp;',
					'<{subject}>&nbsp;',
					'<{source}>&nbsp;',
					'<{created}>&nbsp;',
					'<{modified}>&nbsp;',
				))."</td></tr>\n",
			},
			'flag'	=> {		# h
				'description'	=> 'html flag template', 
				'repeat'		=> 10,
				'header'		=> q#
<tr>
<td><b><{key}></b></td><td><b>Bug ids</b></td><td><b>Created</b></td><td><b>Modified</b></td>
</tr>
#,
				'body'			=> q#
<tr valign="top">
<td><{id4key}>: <{name}></td>
<td>Bug ids: <{bug_count}></td>
<td>Created: <{created}></td><td>Modified: <{created}></td>
</tr>
#,
			},
		},
		'object'	=> {		# OBJECT h
			'bug'	=> {		# h
				'description'	=> 'html bug template', 
				'repeat'		=> 10,
				'footer'		=> '',
				'header'		=> # '<tr><td colspan=15><hr></td></tr>',
					'<tr><td>'.join('</td><td>', (
					'<b>&nbsp;</b>',
					'<b>Bugid</b>',
					'<b>Status</b>',
					'<b>version</b>',
					'<b>Group</b>',
					'<b>Severity</b>',
					'<b>Change ids</b>',
					'<b>Note ids</b>',
					'<b>Patch ids</b>',
					'<b>Test ids</b>',
					'<b>User ids</b>',
					'<b>Subject</b>',
					'<b>Osname</b>',
					'<b>Fixed in</b>',
				))."</td></tr>\n",
				'body'			=> '<tr valign="top"><td>'.join('</td><td>', (
					'<{ifadmin}><{select}></{ifadmin}>&nbsp;',
					'<{bugid}>&nbsp;',
					'<{status_names}>&nbsp;', 
					'<{version_names}>&nbsp;', 
					'<{group_names}>&nbsp;', 
					'<{severity_names}>&nbsp;', 
					'<{change_count}>&nbsp;',
					'<{note_count}>&nbsp;', 
					'<{patch_count}>&nbsp;',
					'<{test_count}>&nbsp;', 
					'<{user_count}>&nbsp;',
					'<{subject}>&nbsp;',
					'<{osname_names}>&nbsp;', 
					'<{fixed_names}>&nbsp;', 
				))."</td></tr>\n",
			},
			'group' => {		# h
				'description'	=> 'html group template', 
				'repeat'		=> 10,
				'header'		=> q#
<tr>
	<td><b>&nbsp;</b></td>
	<td><b>groupid</b></td>
	<td><b>name</b></td>
	<td><b>userids</b></td>
	<td><b>bugids</b></td>
	<td><b>description</b></td>
	<td><b>created</b></td>
	<td><b>modified</b></td>
</tr>
#,
				'body'			=> q#
<tr>
	<td> <{ifadmin}> <{select}> </{ifadmin}> &nbsp;</td>
	<td><{groupid}> &nbsp;</td>
	<td><{name}> &nbsp;</td>
	<td><{user_count}> &nbsp;</td>
	<td><{bug_count}> &nbsp;</td>
	<td><{description}> &nbsp;</td>
	<td><{created}> &nbsp;</td>
	<td><{modified}> &nbsp;</td>
</tr>
#,
			},
			'user'	=> {		# h
				'description'	=> 'html user template', 
				'repeat'		=> 10,
				'header'		=> q#
<tr>
	<td><b>&nbsp;</b></td>
	<td><b>Userid</b></td>
	<td><b>Name</b></td>
	<td><b>Bugids</b></td>
	<td><b>Groups</b></td>
	<td><b>Address</b></td>
	<td><b>Created</b></td>
	<td><b>Modified</b></td>
</tr>
#,
				'body'			=> q#
<tr>
	<td> <{ifadmin}> <{select}> </{ifadmin}> &nbsp;</td>
	<td><{userid}> &nbsp;</td>
	<td><{name}> &nbsp;</td>
	<td><{bug_count}> &nbsp;</td>
	<td><{group_names}> &nbsp;</td>
	<td><{address}> &nbsp;</td>
	<td><{created}> &nbsp;</td>
	<td><{modified}> &nbsp;</td>
</tr>
<tr><td colspan=7>&nbsp;</td></tr>
#, 
			},
		},
	},	# end h
	'I'	=> {					# INDEX - html
		'default'	=> {		# DEFAULT I
			# 'application'	=>  # I
			'flag'	=> {		# I
				'description'	=> 'INDEX flag template', 
				'repeat'		=> 25,
				'header'		=> qq#<b><{key}></b> ids:<br>\n#,
				'body'			=> qq#<{id4key}><br>\n#,
			},
			'item'	=> {		# I
				'description'	=> 'INDEX item template', 
				'repeat'		=> 25,
				'header'		=> qq#<b><{key}></b> ids:<br>\n#,
				'body'			=> qq#<{id4key}><br>\n#,
			},
			'mail'	=> {		# I
				'description'	=> 'INDEX mail template', 
				'repeat'		=> 25,
				'header'		=> qq#<b><{key}></b> ids:<br>\n#,
				'body'			=> qq#<{id4key}><br>\n#,
			},
		},
	},	# end I
	'i'	=> {					# index - short
		'default'	=> {		# DEFAULT i
			# 'application'	=>  # i
			'flag'	=> {		# i
				'description'	=> 'index flag template', 
				'repeat'		=> 25,
				'header'		=> qq#<{key}> ids:\n#,
				'body'			=> qq#<{id4key}>\n#,
			},
			'item'	=> {		# i
				'description'	=> 'index item template', 
				'repeat'		=> 25,
				'header'		=> qq#<{key}> ids:\n#,
				'body'			=> qq#<{id4key}>\n#,
			},
			'mail'	=> {		# i
				'description'	=> 'index mail template', 
				'repeat'		=> 25,
				'header'		=> qq#<{key}> ids:\n#,
				'body'			=> qq#<{id4key}>\n#,
			},
		},
	},	# end i
	'L'	=> {					# List - html 
		'default'	=> {		# DEFAULT L
			# 'application'	=>  # L
			'flag'	=> {		# L
				'description'	=> 'LIST flag template', 
				'repeat'		=> 10,
				'header'		=> '<tr><td>'.join('</td><td>', (
					'<b>&nbsp;</b>',
					'<b><{key}> ids</b>',
					'<b>Bug ids</b>',
					'<b>Created</b>',
					'<b>modified</b>',
				))."</td></tr>\n",
				'body'			=> '<tr><td>'.join('</td><td>', (
					'<{ifadmin}><{select}></{ifadmin}>',
					'<{id4key}>',
					'<{bug_count}>',
					'<{created}>',
					'<{modified}>',
				))."</td></tr>\n",
			},
			'item'	=> {		# L
				'description'	=> 'LIST item template', 
				'repeat'		=> 10,
				'header'		=> '<tr><td>'.join('</td><td>', (
					'<b>&nbsp;</b>',
					'<b><{key}> ids</b>',
					'<b>Bug ids</b>',
					'<b>created</b>',
					'<b>modified</b>',
				))."</td></tr>\n",
				'body'			=> '<tr><td>'.join('</td><td>', (
					'<{ifadmin}><{select}></{ifadmin}>',
					'<{id4key}>',
					'<{bug_count}>',
					'<{created}>',
					'<{modified}>',
				))."</td></tr>\n",
			},
			'mail'	=> {		# L
				'description'	=> 'LIST mail template', 
				'repeat'		=> 10,
				'header'		=> '<tr><td>'.join('</td><td>', (
					'<b>&nbsp;</b>',
					'<b><{key}> ids</b>',
					'<b>Bug ids</b>',
					'<b>Subject</b>',
				))."</td></tr>\n",
				'body'			=> '<tr><td>'.join('</td><td>', (
					'<{ifadmin}><{select}></{ifadmin}>',
					'<{id4key}>',
					'<{bug_count}>',
					'<{subject}>',
				))."</td></tr>\n",
			},
		},
		'object'	=> {
			'bug'	=> {		# L
				'description'	=> 'LIST bug template', 
				'header'		=> # '<tr><td colspan=15><hr></td></tr>',
					'<tr><td>'.join('</td><td>', (
					'<b>&nbsp;</b>',
					'<b>bugid</b>',
					'<b>status</b>',
					'<b>version</b>',
					'<b>group</b>',
					'<b>severity</b>',
					'<b>note ids</b>',
					'<b>patch ids</b>',
					'<b>test ids</b>',
					'<b>user ids</b>',
					'<b>subject</b>',
					'<b>osname</b>',
				))."</td></tr>\n",
				'repeat'		=> 10,
				'body'			=> '<tr><td>'.join('</td><td>', (
					'<{ifadmin}><{select}></{ifadmin}>',
					'<{bugid}>&nbsp;',
					'<{status_names}>&nbsp;', 
					'<{version_names}>&nbsp;', 
					'<{group_names}>&nbsp;', 
					'<{severity_names}>&nbsp;', 
					'<{note_count}>&nbsp;', 
					'<{patch_count}>&nbsp;',
					'<{test_count}>&nbsp;', 
					'<{user_count}>&nbsp;',
					'<{subject}>&nbsp;',
					'<{osname_names}>&nbsp;', 
				))."</td></tr>\n",
			},
		},	
	},	# end L
	'l'	=> {					# list - short
		'default'	=> {		# DEFAULT l
			# 'application'	=> {		# l
			'flag'	=> {		# l
				'description'	=> 'list flag template', 
				'repeat'		=> 10,
				'header'		=> qq#<{key}>:\n#,
				'body'			=> q#<{id4key}3>  <{name}>  bugids: <{bug_count}5> - Created: <{created}> 
#,
			},
			'item'	=> {		# l
				'description'	=> 'list item template', 
				'repeat'		=> 10,
				'header'		=> qq#<{key}>:\n#,
				'body'			=> q#<{id4key}3>  <{name}>  bugids: <{bug_count}5> - Created: <{created}> 
#,
			},
			'mail'	=> {		# l
				'description'	=> 'list mail template', 
				'repeat'		=> 10,
				'header'		=> qq#<{key}>:\n#,
				'body'			=> q#<{id4key}3>  bugids: <{bug_count}5> - Subject: <{subject}>
#,
			},
		},
		'object'	=> {	
			'bug'	=> {		# l
				'description'	=> 'list bug template', 
				'repeat'		=> 10,
				'header'		=> q#bugid         messageids  subject 
#,
				'body'			=> q#<{bugid}13> <{message_count}10>  <{subject}>
#,
			},
			'group'	=> {		# l
				'description'	=> 'list group template', 
				'repeat'		=> 10,
				'header'		=> q#groupid     name             bugs     description 
#,
				'body'			=> q#<{groupid}10>  <{name}15>  <{bug_count}7>  <{description}>
#,
			},
			'user'	=> {		# l
				'description'	=> 'list user template', 
				'repeat'		=> 10,
				'header'		=> q#userid      name                       bugs     address 
#,
				'body'			=> q#<{userid}10>  <{name}25>  <{bug_count}7>  <{address}>
#,
			},
		},
	},	# end l
);

# $o_tmp->template

my $err    = 0;
my $test   = 0;
my $i_inst = 0;
my @oids   = ();
my $i_wanted = scalar(keys %TEMPLATES);

plan('tests' => $i_wanted);

FORMAT:
foreach my $format (sort keys %TEMPLATES) {					# 'a' => []
	my $h_format = $TEMPLATES{$format};						# 'h' => []
	next FORMAT unless ref($h_format) eq 'HASH'; 
	$test++;
	next FORMAT unless $format =~ /$f/;
	output("[$f] -> format($format)");

	DEFOBJ:
	foreach my $defobj (sort keys %{$h_format}) {
		my $h_defobj = $$h_format{$defobj};					# 'object'	=> {} or
		next DEFOBJ unless ref($h_defobj) eq 'HASH';		# 'default'	=> {} 
		next DEFOBJ unless $defobj =~ /$x/;
		output("[$x] --> defobj($defobj)");

		OBJECTTYPE:
		foreach my $objtype (sort keys %{$h_defobj}) {		# 'bug'		=> {} object 
			my $h_temp = $$h_defobj{$objtype};				# 'mail'	=> {} or default
			next OBJECTTYPE unless ref($h_temp) eq 'HASH'; 
			next OBJECTTYPE unless $objtype =~ /$o/;
			next OBJECTTYPE unless $$h_temp{'body'} =~ /\w+/;
			output("[$o] ---> objtype($objtype)");

			my $i_ok   = 1;
			my $o_tmp  = $o_pb->object('template');
			my $pri    = $o_tmp->attr('primary_key');
			my $oid    = $o_tmp->new_id;
			my ($object, $type) = (($defobj eq 'default') ? ('', $objtype) : ($objtype, ''));
			my %data = (
				'body'			=> "no template body\n", 
				'description'	=> "$format $objtype template ($defobj)", 
				'format' 		=> $format,
				'header'		=> '',
				'repeat'		=> '0',
				'footer'		=> '',
				'wrap'			=> '',
				'object' 		=> $object,
				'type' 			=> $type, 
				%{$h_temp},
				$pri     		=> $oid, 
			);

			my $cond = "object = '$object' AND type = '$type' AND ".
				$o_pb->db->case_sensitive('format', $format);
			my @exists = $o_tmp->col('templateid', $cond);
			my @userids = ();
			if (@exists) {
				output("existing($cond) records(@exists)!");
				if ($F) { # rjsf: _NOT_ if related to anybody!
					my $exists = join("', '", @exists);
					@userids = $o_tmp->rel('user')->ids("templateid IN('$exists')");
					$i_ok = $o_tmp->delete(\@exists)->DELETED;
					output("repeating insert deleted($i_ok)");
				} else {
					output("not repeating insert! -F ?");
					$i_ok = 0;
				}
			}

			$i_ok = $o_tmp->create(\%data)->CREATED if $i_ok;

			if ($i_ok != 1) {
				output("\tfailed to insert $o_tmp($i_ok)!"); 
				$err++;
			} else {	
				my $oid = $o_tmp->oid;
				push(@oids, $oid);
				$i_ok = 0 unless $oid =~ /^\d+$/;
				# if ($F) { # rjsf: _NOT_ if related to anybody!
				$o_tmp->delete([$oid]) if $t;	
				output("\tinstalled => oid($oid)");
				# if ($F) { # rjsf: _NOT_ if related to anybody!
				if ($i_ok == 1) { # !
					$i_inst++;
					my @users = (split(':', $u), @userids);
					my $i_del = $o_tmp->rel('user')->delete(\@exists)->DELETED;
					my $i_rel = $o_tmp->relate({ 'user' => { 'ids' => \@users }, });
					output("\trelated to user(@users)");
				}
			} 
			ok(($i_ok == 1) ? $test : 0);
		}
	}
}
if ($err == 0) {	
	output("...installed $i_inst templates(@oids)");
} else {
	output("...failed($err) of $i_wanted types(".join(', ', keys %TEMPLATES).") of template installations ok($i_inst)"); 
}
   
# done.

