package Test::BDD::Cucumber::Definitions::Types;

use strict;
use warnings;

use DDP ( show_unicode => 1 );
use MooseX::Types::Common::String qw(NonEmptyStr);
use MooseX::Types::Moose qw(Int Str RegexpRef);
use Test::BDD::Cucumber::Definitions qw(S);
use Test::More;
use Try::Tiny;

use MooseX::Types (
    -declare => [
        qw(
            TbcdInt
            TbcdStr
            TbcdNonEmptyStr
            TbcdRegexpRef
            )
    ]
);

our $VERSION = '0.38';

# Interpolation of variables (scenario and environment)
sub _interpolate {
    my ($value) = @_;

    my $orig = $value;

    # Scenario variables
    my $is = $value =~ s| S\{ (.+?) \} |
        S->{Var}->scenario($1) // q{};
    |gxe;

    # Environment variables
    my $ie = $value =~ s/ \$\{ (.+?) \} /
        $ENV{$1} || '';
    /gxe;

    if ( $is || $ie ) {
        diag( sprintf( q{Inteprolated value "%s" = %s}, $orig, np $value) );
    }

    return $value;
}

# TbcdInt
subtype(
    TbcdInt,
    as Int,
    message {
        sprintf( '%s is not a valid TBCD Int', np $_);
    }
);

coerce(
    TbcdInt,
    from Str,
    via { _interpolate $_}
);

# TbcdStr
subtype(
    TbcdStr,
    as Str,
    message {
        sprintf( '%s is not a valid TBCD Str', np $_);
    }
);

coerce(
    TbcdStr,
    from Str,
    via { _interpolate $_}
);

# TbcdNonEmptyStr
subtype(
    TbcdNonEmptyStr,
    as NonEmptyStr,
    message {
        sprintf( '%s is not a valid TBCD NonEmptyStr', np $_);
    }
);

coerce(
    TbcdNonEmptyStr,
    from NonEmptyStr,
    via { _interpolate $_}
);

# TbcdRegexpRef
subtype(
    TbcdRegexpRef,
    as RegexpRef,
    message {
        sprintf( '%s is not a valid TBCD RegexpRef', np $_);
    }
);

coerce(
    TbcdRegexpRef,
    from Str,
    via {
        my $value = _interpolate $_;

        try {
            qr/$value/;    ## no critic [RegularExpressions::RequireExtendedFormatting]
        }
        catch {
            return $value;
        };
    }
);

1;
