# -*-perl-*-

# $Id: HostAttributes.plm,v 1.7 2006/04/11 14:35:28 thomas Exp $

# $Log: HostAttributes.plm,v $
# Revision 1.7  2006/04/11 14:35:28  thomas
# Mke it more purdy
#
# Revision 1.6  2005/01/27 15:52:05  thomas
# Don't die on text parse failure
#
# Revision 1.5  2004/11/05 16:15:36  thomas
# Fix check for "line contains only whitespace."
#
# Revision 1.4  2004/10/13 16:05:42  thomas
# db version
#
# Revision 1.3  2004/07/02 19:03:04  thomas
# documentation update
#
# Revision 1.2  2004/06/08 16:11:24  thomas
# Move attribute list culling and fixing to HostAttributes
#
# Revision 1.1  2004/06/08 14:22:28  thomas
# Provide access to host attribute lists
#

=head1 NAME

B<HostAttributes.pm> - Maintain host attributes

=head1 SYNOPSIS

  use What::HostAttributes;

  my $attrs = new What::HostAttributes (%opts);

  my @$hosts = $attrs->find ();
  my $text = $attrs->find ($host);
  my $text = $attrs->lock ($host);
  my $ret = $attrs->unlock ();
  my $ret = $attrs->set ($host, $text);
  my $ret = $attrs->drop ($host);

  my $ret = $attrs->close(%opts);

  my @$attrs = $attrs->parse_attrs ($text);

=head1 DESCRIPTION

This module updates, queries, loads and saves a database of B<What>
host attribute (i.e. top level include) information.

This information is combined with B<csdb> data for OS type and
monitoring information to produce an B<xml> file for each host known
to B<What>.

=head1 METHODS

=over 4

=cut

package What::HostAttributes;

use strict;
use Text::ParseWords;

use base qw(What::MultiData);

###############################################################################

=item @$attrs = $self->parse_attrs ($text);

Take $text (lines separated by newline characters) and parse them into
an attribute structure.  The format of the structure is:

An array.  Each element of the array is:

A hash ref.  The elements of the has ref are:

file => the name (absolute, partial, or relative) or the xml file to load.
params => a hash ref of parameter names and values to pass
comments => The lines that preceeded this attribute that began with '#'

=cut

sub parse_attrs {
  my $self = shift;
  my $text = shift;

  my (@attrs, @words, $line, $attr, $param, $comments);

  $comments = [];
  defined ($text) or $text = '';
  foreach $line (split (/\n/, $text)) {
    chomp $line;
    $line =~ s/^\s+//;
    $line =~ s/^\s+$// and next;

    if ($line =~ /^\#/ || $line =~ /^\s*$/) {
      chomp ($line);
      $line =~ s/^\#\s?//;
      push @$comments, $line;
      next;
    }

    # First word is the file name
    @words = shellwords ($line);
    $attr = {
	     file => $words[0],
	     comments => $comments,
	     params => {},
	    };
    shift @words;
    $comments = [];
    foreach $param (@words) {
      if ($param =~ /(.+)=(.+)/) {
	$attr->{params}->{$1} = $2;
      } else {
	printf STDERR "failed to parse param %s!\n", $param;
	return undef;
      }
    }
    push @attrs, $attr;
  }
  [@attrs];
}

###############################################################################

1;

# End the documentation

=back

=head1 SEE ALSO

What::Command::edithost

What::MultiData
