#!perl
#
# foodratio - calculate ingredient ratios

use 5.26.0;
use warnings;
use Food::Ratio;
use Getopt::Long 'GetOptions';

my ( $mass, @ratio_args, @weigh_args );
GetOptions(
    'mass=f' => sub {
        die "foodratio: mass must be a positive number\n" unless $_[1] > 0;
        $mass = $_[1];
    },
    'ratio=s' => sub {
        my ( $key, $value ) = split ':', $_[1], 2;
        die "foodratio: ratio key must be 'id' or 'group'\n"
          unless $key eq 'id' or $key eq 'group';
        @ratio_args = ( $key, $value );
    },
    'weigh=s' => sub {
        my ( $key, $value ) = split ':', $_[1], 2;
        die "foodratio: weigh key must be 'id' or 'group'\n"
          unless $key eq 'id' or $key eq 'group';
        @weigh_args = ( $key, $value );
    },
) or exit 64;

my $fr = Food::Ratio->new;

while ( my $line = readline ) {
    chomp $line;
    my ( $mass, $name, @rest ) = split ' ', $line;
    # probably the 2nd column is ratios, assume name is in next column
    $name = shift @rest if $name =~ m/[%]/;
    $fr->add( $mass, $name, @rest );
}
$fr->ratio(@ratio_args);

$fr->weigh( $mass, @weigh_args ) if defined $mass;

print $fr->string;

__END__

=head1 NAME

foodratio - calculate ingredient ratios

=head1 SYNOPSIS

  $ cat recipe
  1 egg   wet
  2 water wet
  4 flour dry
  $ foodratio recipe
  $ foodratio --ratio id:flour
  $ foodratio --mass 55 --weigh group:wet

=head1 DESCRIPTION

Given a list of measurements of ingredients, foodratio will calculate
the ratio between those various inputs, optionally using some ingredient
(or group of ingredients) as the ratio key. The weights can be
recalculated based on the measurement of a particular ingredient.

The input should be in columns, with the mass (or whatever measurement)
as the first column. This must be a strictly positive number. If the
second column contains C<%> it will be ignored, on the presumption that
that is a ratio. Thus the name (id) of the ingredient will come from
either the second or third column. The remainder of the columns, if
any, will be treated as group names that collect ingredients into
groups, e.g. a custom C<flour> group for recipes with different types
of flour, or so forth.

=head2 Options

=over 4

=item B<mass> I<positive-number>

Sets the mass for the B<weigh> method; ingredient measurements will be
recalculated based on this amount.

=item B<ratio> I<key:value>

Sets the ingredient or ingredient group to use as the key value for
the ratio calculation, e.g. flour in a bread recipe and not the
default total mass. I<key> must be C<id> or C<group>.

=item B<weigh> I<key:value>

Sets the ingredient or ingredient group to use as the basis for the
B<mass> argument, which by default is otherwise the total mass.

=back

=head1 SEE ALSO

L<Food::Ratio>

=head1 COPYRIGHT AND LICENSE

Copyright 2022 Jeremy Mates

This program is distributed under the (Revised) BSD License:
L<https://opensource.org/licenses/BSD-3-Clause>

=cut
