package DX::Hypothesis;

use DX::Class;

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

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

has outstanding_propositions => (is => 'ro', required => 1);

has actions => (is => 'ro', required => 1);

sub head_proposition { shift->outstanding_propositions->[0] }

sub with_actions {
  my ($self, @actions) = @_;
  my $hyp = $self;
  foreach my $act (@actions) {
    ($hyp, my @events) = $act->dry_run($hyp);
    return undef unless $hyp;
    $hyp = $hyp->but_recheck_for(@events);
    return undef unless $hyp;
  }
  return $hyp;
}

sub but_recheck_for {
  my ($self, @events) = @_;
  my ($still_resolved, @recheck) = $self->resolved_propositions
                                        ->but_expire_for(@events);
  my $hyp = $self->but(resolved_propositions => $still_resolved);
  $hyp = $_->but_recheck_against($hyp) or return undef for @recheck;
  return $hyp;
}

sub resolve_head_dependent_on {
  my ($self, $depends) = @_;
  my ($first, @rest) = @{$self->outstanding_propositions};
  $self->but(
    resolved_propositions => $self->resolved_propositions
                                  ->with_resolution_for(
                                      $first,
                                      $depends,
                                    ),
    outstanding_propositions => \@rest,
  );
}

1;
