package DX::Hypothesis;

use DX::ActionPolicy::LockScope;
use DX::Utils qw(deparse);
use DX::Class;

has scope => (is => 'ro', isa => Scope, required => 1);

has resolved_propositions => (
  is => 'ro', isa => ResolvedPropositionSet, required => 1
);

has actions => (
  is => 'ro', isa => ArrayRef[Action], required => 1
);

has action_applications => (
  is => 'ro', isa => ArrayRef[Action], required => 1
);

has action_policy => (is => 'ro', isa => ActionPolicy, required => 1);

sub with_actions {
  my ($self, @actions) = @_;
  my $hyp = $self;
  my @events;
  foreach my $act (@actions) {
    return undef unless $self->action_policy->allows($act);
    ($hyp, my @these_events) = $act->dry_run($hyp);
    return undef unless $hyp;
    push @events, @these_events;
  }
  my ($still_resolved, @recheck) = $hyp->resolved_propositions
                                       ->but_expire_for(@events);
  return (
    $hyp->but(resolved_propositions => $still_resolved),
    @recheck
  );
}

sub with_resolution {
  my ($self, $prop, $depends, $actions) = @_;
  (my $hyp, my @recheck) = $self->with_actions(@$actions);
  return undef unless $hyp;
  return (
    $hyp->but(
      resolved_propositions => $self->resolved_propositions
                                    ->with_resolution_for(
                                        $prop,
                                        $depends,
                                      ),
    ),
    @recheck
  );
}

1;
