package Tak::EvalService;

use Eval::WithLexicals;
use Moo;
use Data::Dumper::Concise;
use Capture::Tiny qw(capture);

has 'eval_withlexicals' => (is => 'lazy');

sub _build_eval_withlexicals {
  Eval::WithLexicals->new
}

sub handle_eval {
  my ($self, $perl) = @_;
  unless ($perl) {
    return MISTAKE => eval_input => "No code supplied";
  }
  if (my $ref = ref($perl)) {
    return MISTAKE => eval_input => "Code was a ${ref} reference";
  }
  my ($code, @ret);
  my ($stdout, $stderr);
  if (eval {
    ($stdout, $stderr) = capture {
      @ret = $self->eval_withlexicals->eval($perl);
    };
    1
  }) {
    $code = 'RESULT';
  } else {
    ($code, @ret) = (FAILURE => $@);
  }
  my $dumped_ret;
  unless (eval { $dumped_ret = Dumper(@ret); 1 }) {
    $dumped_ret = "Error dumping ${code} result: $@";
    $code = 'FAILURE';
  }
  return $code => {
    stdout => $stdout, stderr => $stderr, return => $dumped_ret
  };
}

1;
