# $Id: LogLevel.pm,v 1.5 2008-03-26 14:43:25 mike Exp $

package Keystone::Resolver::LogLevel;

use strict;
use warnings;


=head1 NAME

Keystone::Resolver::LogLevel - logging levels for Keystone Resolver

=head1 SYNOPSIS

 $resolver->option(loglevel => (Keystone::Resolver::LogLevel::CHITCHAT &
                                Keystone::Resolver::LogLevel::CACHECHECK));
 print Keystone::Resolver::LogLevel::label(Keystone::Resolver::LogLevel::PARSEXSLT);

=head1 DESCRIPTION

This trivial class supplies a set of symbolic constants for the
bitmasks used in log-levels for Keystone Resolver logs.  These may be
arithmetrically ORred together to provide the resolver with a
requested logging level consisting of more than one of the levels
defined here.

=head1 LOGGING LEVELS

=over 4

=item CHITCHAT

Notify events of general interest such as starting up and shutting
down.  (DEADLY WARNING: Only use this if you like that kind of thing.)

=item CACHECHECK

Notify when checking for the existence of any kind of object in a
cache.

=item PARSEXSLT

Notify when parsing an XSLT stylesheet.

=item DUMPDESCRIPTORS

Dump the contents of the parsed descriptors.

=item SHOWGENRE

Dump the referent object before trying to resolve it.

=item SHOWGENRE

Show the genre (both ID and name) of each object resolved.

=item DBLOOKUP

Show the results of looking up IDs and tags in the resource database.

=item MKRESULT

Show the results of looking up IDs and tags in the resource database.

=item SQL

Show SQL statements before executing them.

=item DEREFERENCE

Indicate when an element of an OpenURL is dereferenced.  This includes
both a By-Reference ContextObject, and individual entities that are
specified by reference.

=item DISSECT

Indicate when a By-Value OpenURL (including one in which that value
was fetched because it was originally By-Reference) is dissected into
KEV elements.

=item RESOLVEID

Indicate when any kind of identifier (DOI, PubMed ID, etc.) is
resolved, and what the results are.

=item CONVERT01

Log the conversion of OpenURL v0.1 parameters to their v1.0
equivalents, and the creation of additional parameters required by
v1.0.

=item HANDLE

Indicate when a service handles a request, and whether the result is a
usable URL or a fatal or non-fatal error.

=item WARNING

Warnings generated by bad recipes and suchlike.

=item LIFECYCLE

Information about the creation and destruction of objects such as
resolvers and databases, whether explicit or garbage-collected.

=back

=cut

sub CHITCHAT        {    0x1 }
sub CACHECHECK      {    0x2 }
sub PARSEXSLT       {    0x4 }
sub DUMPDESCRIPTORS {    0x8 }
sub DUMPREFERENT    {   0x10 }
sub SHOWGENRE       {   0x20 }
sub DBLOOKUP        {   0x40 }
sub MKRESULT        {   0x80 }
sub SQL             {  0x100 }
sub DEREFERENCE     {  0x200 }
sub DISSECT         {  0x400 }
sub RESOLVEID       {  0x800 }
sub CONVERT01       { 0x1000 }
sub HANDLE          { 0x2000 }
sub WARNING         { 0x4000 }
sub LIFECYCLE       { 0x8000 }


=head1 METHODS

=cut


=head2 num()

 print Keystone::Resolver::LogLevel::num("parsexslt,sql");

Returns a numeric value representing the comma-separated set of
logging levels listed in the argument -- namely, the sum of the values
corresponding to each individual level.  It is a fatal error to
include an undefined logging-level name.

=cut

my %str2num = (
	       CHITCHAT => CHITCHAT,
	       CACHECHECK => CACHECHECK,
	       PARSEXSLT => PARSEXSLT,
	       DUMPDESCRIPTORS => DUMPDESCRIPTORS,
	       DUMPREFERENT => DUMPREFERENT,
	       SHOWGENRE => SHOWGENRE,
	       DBLOOKUP => DBLOOKUP,
	       MKRESULT => MKRESULT,
	       SQL => SQL,
	       DEREFERENCE => DEREFERENCE,
	       DISSECT => DISSECT,
	       RESOLVEID => RESOLVEID,
	       CONVERT01 => CONVERT01,
	       HANDLE => HANDLE,
	       WARNING => WARNING,
	       LIFECYCLE => LIFECYCLE,
	       );

sub num {
    my($str) = @_;

    my $num = 0;
    foreach my $comp (split /,/, uc($str)) {
	my $val = $str2num{$comp};
	die "no loglevel called '$comp'" if !defined $val;
	$num += $val;
    }

    return $num;
}


=head2 label()

 print Keystone::Resolver::LogLevel::label(Resolver::LogLevel::PARSEXSLT |
                                           Resolver::LogLevel::SQL);

Returns a short human-readable string describing the combination of
logging-levels specified as the argument.

=cut

my %num2str = reverse %str2num;

sub label {
    my($level) = @_;

    my @res;

    foreach my $exp (0..31) {
	my $val = 1 << $exp;
	if ($level & $val) {
	    my $str = $num2str{$val};
	    die "no loglevel string for 1<<$exp == $val" if !defined $str;
	    push @res, $str;
	}
    }

    return "[empty]" if @res == 0;
    return join(",", @res);
}


1;
