#!/usr/bin/env perl
# PODNAME: bee
# ABSTRACT: Small application to handle bee files
our $VERSION = '0.200';

use strict;
use warnings;
use Carp qw( croak );
use BeePack;
use File::Temp qw/ tmpnam /;
use Data::Dumper;

my $beepack = shift @ARGV;

my $key = shift @ARGV;
my $type = shift @ARGV;
my @values = @ARGV;
my $tmpfile = tmpnam();
my @args = ( $beepack, defined $type ? ( $tmpfile ) : () );
my $bee = BeePack->open(@args);

if (defined $key) {
  if (defined $type) {
    if ($type =~ m/^n/) {
      croak("nil type can't have a value") if scalar @values > 0;
      $bee->set_nil($key);
    } elsif ($type =~ m/^i/) {
      croak("integer can only handle one value") if scalar @values > 1;
      $bee->set_integer($key,$values[0]);
    } elsif ($type =~ m/^s/) {
      croak("string can only handle one value") if scalar @values > 1;
      $bee->set_string($key,$values[0]);
    } elsif ($type =~ m/^b/) {
      croak("bool can only handle one value") if scalar @values > 1;
      $bee->set_bool($key,$values[0]);
    } elsif ($type =~ m/^a/) {
      $bee->set($key,\@values);
    } elsif ($type =~ m/^h/) {
      croak("hash needs even number") if scalar @values % 2;
      $bee->set($key,{ @values });
    } else {
      croak("Unknown type ".$type);
    }
    $bee->save;
  } else {
    my $val = $bee->get($key);
    if (defined $val) {
      my $ref = ref $val;
      if ($ref eq 'ARRAY' || $ref eq 'HASH') {
        print Dumper $val;
      } else {
        print $val;
      }
    }
  }
} else {
  for ($bee->keys) {
    print $_."\n";
  }
}

exit 0;

__END__

=pod

=encoding UTF-8

=head1 NAME

bee - Small application to handle bee files

=head1 VERSION

version 0.200

=head1 SYNOPSIS

  # show keys
  $ bee test.bee

  # get key
  # integer displays as ascii numbers
  # bool displays as true or false
  # nil value is not displayed
  # arrays and hashs are displayed as Data::Dumper dump
  $ bee test.bee key

  # sample complex key, no need for escaping
  $ bee test.bee web#img/background.jpg#content

  # get is transparent on string
  $ bee test.bee gzipped_value | gunzip -c

  # set key to nil
  $ bee test.bee key n

  # set bool key
  $ bee test.bee key b 0

  # set integer key
  $ bee test.bee key i 123

  # set string key
  $ bee test.bee key s "This is a test"

  # set array key
  $ bee test.bee key a "Peter Parker" "Bruce Banner" "Clark Jerome Kent"

  # set hash key
  $ bee test.bee key h \
    spiderman "Peter Parker" \
    hulk "Bruce Banner" \
    superman "Clark Jerome Kent"

=head1 DESCRIPTION

C<bee> is a small command-line tool, bundled with L<BeePack>, for inspecting
and manipulating a C<.bee> file directly from the shell. It takes up to three
leading arguments -- C<bee FILE [KEY [TYPE VALUE...]]> -- and picks its mode
from how many of them are given:

=over 4

=item C<bee FILE>

No C<KEY>: opens C<FILE> read-only and lists every key in the pack, one per
line.

=item C<bee FILE KEY>

A C<KEY> but no C<TYPE>: opens C<FILE> read-only and prints the value stored
under C<KEY> -- arrays and hashes via L<Data::Dumper>, everything else as-is.
A key that doesn't "exist" (see L<BeePack/nil_exists>; by default this
includes a nil-valued key) prints nothing.

=item C<bee FILE KEY TYPE VALUE...>

A C<TYPE> as well: opens C<FILE> read/write (through a tempfile), sets C<KEY>
to C<VALUE...> forced into the MsgPack type named by C<TYPE>, and saves.

=back

C<TYPE> is matched on its first character, mirroring L<BeePack/set_type> --
adding a new letter here means adding the matching branch there, and vice
versa.

=head2 n

Nil. Takes no C<VALUE>. Sets C<KEY> to MsgPack nil via
L<BeePack/set_nil>.

=head2 i

Integer. Takes exactly one C<VALUE>, forced to a MsgPack integer via
L<BeePack/set_integer>.

=head2 s

String. Takes exactly one C<VALUE>, forced to a MsgPack string via
L<BeePack/set_string>.

=head2 b

Bool. Takes exactly one C<VALUE>; L<BeePack/set_bool> stores it as MsgPack
C<true> or C<false> according to whether C<VALUE> is true or false in Perl
terms (so C<0> and the empty string store as false).

=head2 a

Array. Every remaining C<VALUE> is stored as one MsgPack array.

=head2 h

Hash. Every remaining C<VALUE> is stored as one MsgPack hash -- an even count
of C<KEY VALUE KEY VALUE ...> pairs is required.

=head2 Storing a numeric-looking value as a string

  $ bee test.bee key s 0042

=head2 Streaming a raw value through a pipe

  $ bee test.bee gzipped_value | gunzip -c

=head1 SUPPORT

=head2 Issues

Please report bugs and feature requests on GitHub at
L<https://github.com/cindustries/p5-beepack/issues>.

=head1 CONTRIBUTING

Contributions are welcome! Please fork the repository and submit a pull request.

=head1 AUTHOR

Torsten Raudssus <torsten@raudss.us>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2014-2026 by Torsten Raudssus.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
