package DX::SearchProcess;

use DX::SearchState;
use DX::Class;

has current_search_state => (
  is => 'ro', isa => SearchState, required => 1,
  handles => [ qw(
    current_hypothesis next_step propositions alternatives
  ) ],
);

sub new_for {
  my ($class, $hyp, $props) = @_;
  $class->new(
    current_search_state => DX::SearchState->new_for($hyp, $props),
  );
}

sub with_one_step {
  my ($self) = @_;
  my $new_ss = $self->current_search_state->with_one_step;
  return undef unless $new_ss;
  return $self->but(current_search_state => $new_ss);
}

sub find_solution {
  my ($self) = @_;
  my $state = $self->current_search_state;
  while ($state and (not $state->is_solution_state)) {
    $state = $state->with_one_step;
  }
  return undef unless $state;
  trace 'search.solution.hyp' => $state->current_hypothesis;
  return $self->but(current_search_state => $state);
}

sub force_backtrack {
  my ($self) = @_;
  my $new_ss = $self->current_search_state->force_backtrack;
  return undef unless $new_ss;
  return $self->but(current_search_state => $new_ss);
}

sub find_next_solution {
  my ($self) = @_;
  return undef unless my $bt = $self->force_backtrack;
  return $bt->find_solution;
}

1;
