package App::Clifton::Component;

# define this up here to avoid uninitialised warnings
sub _debug_self {
  my ($self, $args) = @_;
  "${self}: ".join ', ', map "$_ => ".$args->{$_}, keys %$args;
}

use Log::Contextual qw(:log);
use Moo;

extends 'Moo::Object', 'IO::Async::Notifier';

# we're replacing Notifier's constructor so need to set up its default
has children => (is => 'bare', default => sub { [] });

sub BUILD {
  my ($self, $args) = @_;
  log_debug {
    "Constructing "._debug_self($self, $args);
  };
  if (my $parent = $args->{parent_component}) {
    $parent->add_child($self);
  }
}

sub _new_child {
  my ($self, $class, $args) = @_;
  if ($class->isa('App::Clifton::Component')) {
    $class->new(%{$args||{}}, parent_component => $self);
  } else {
    my $new = $class->new(%{$args||{}});
    $self->add_child($new);
    $new;
  }
}

sub _schedule {
  my ($self, $code) = @_;
  $self->get_loop->later($code);
}

sub DESTROY {
  my ($self) = @_;
  log_debug { "Destroying "._debug_self($self, $self) };
}

1;
