package LIMS::Local::MooseX::Role::Validate;

use warnings;
use strict;

use Moose::Role;
use Data::Dump;

sub DEBUG { warn shift if $ENV{VALIDATION_DEBUG} }

sub validate {
    my ( $class, $data ) = @_;
    my $meta = $class->meta;

    my %errors;
    foreach my $attr ( $meta->compute_all_applicable_attributes ) {
        my $attr_name = $attr->name;
        if ( exists $data->{$attr_name} ) {
            my $value = $data->{$attr_name};

            # don't attempt to set empty values on non-required fields
            unless ( defined($value) && length($value) || $attr->is_required ) {
                delete $data->{$attr_name};
                next;
            }
            if ( my $tc = $attr->type_constraint ) {
                $data->{$attr_name} = $value = $tc->coercion->coerce($value)
                  if ( $tc->has_coercion );
                if ( defined( my $error = $tc->validate($value) ) ) {
                    $errors{$attr_name} = $tc->name;
                    next;
                }
            }
        }
        else {
            $errors{$attr_name} = 'required' if $attr->is_required;
        }
    }
    DEBUG('errors: ' . Data::Dump::dump(\%errors));
    return %errors;
}

1;
