package App::EventStreamr::Roles::ProcessControl;

use v5.010;
use strict;
use warnings;
use Method::Signatures 20140224; # libmethod-signatures-perl
use Proc::Daemon; # libproc-daemon-perl
use Proc::ProcessTable; # libproc-processtable-perl

use Moo::Role; # libmoo-perl

# ABSTRACT: A process role

our $VERSION = '0.5'; # VERSION: Generated by DZP::OurPkg:Version


requires 'cmd','id';

has 'pid' => ( is => 'rw', lazy => 1, builder => 1, clearer => 'clear_pid' );

method _build_pid() {
  my $pt = Proc::ProcessTable->new;

  # Sometimes our processes report a different command than
  # how they were started. Also they often spawn a new detached
  # process, so we can't grab the pid from Proc::Daemon::Init.
  my $regex = $self->cmd_regex ? $self->cmd_regex : $self->cmd;
  my @procs = grep { $_->cmndline =~ /$regex/ } @{ $pt->table };

  if (@procs) {
    $self->info("Process ".$self->id." found with pid=".$procs[0]->pid);
    return $procs[0]->pid;
  } else {
    return 0;
  }
}


method start() {
  my %proc_opts = ( exec_command => $self->cmd );
 
  # Proc::Daemon will exit parent when started  in Void
  my $state = Proc::Daemon::Init( \%proc_opts );
}


method stop() {
  if ($self->pid) {
    kill 9, $self->pid;
    $self->clear_pid;
    return 1;
  }
  return 0;
}


method running() {
  #TODO: pid 0 returns true. Should rework the logic here.
  if ( ! $self->pid ) {

  } elsif ( kill 0, $self->pid ) {
    return 1; 
  }
  $self->clear_pid;
  return 0;
}

with('App::EventStreamr::Roles::Logger');

1;

__END__

=pod

=encoding UTF-8

=head1 NAME

App::EventStreamr::Roles::ProcessControl - A process role

=head1 VERSION

version 0.5

=head1 SYNOPSIS

This is a role that provides 'start', 'stop' and 'running' methods.

=head1 DESCRIPTION

This is a Role that can be consumed to provide process operations
used throughout EventStreamr.

It requires a 'cmd' attribute and will utilise an optional 
'cmd_regex' if one exists.

=head1 METHODS

=head2 start

  $proc->start;

Forks the command and returns.

=head2 stop

  $proc->stop;

Stops the running process if it is found.

=head2 running

  $proc->running;

Returns 1 if running, 0 if not.

=head1 AUTHOR

Leon Wright < techman@cpan.org >

=head1 COPYRIGHT AND LICENSE

This software is Copyright (c) 2014 by Leon Wright.

This is free software, licensed under:

  The GNU Affero General Public License, Version 3, November 2007

=cut
