#!/usr/bin/perl

use v5.10.0;
use strict;
use warnings;

use Ubic::Multiservice::Simple;
use Ubic::Service::SimpleDaemon;
use Exobrain;

# PODNAME: exobrain
# ABSTRACT: UBIC service file for exobrain


# This file is both dispatcher and services file. When
# called with no arguments, we provide UBIC services
# info. When run with arguments, we start services.
#
# At some point it might make sense to split these functions.
#
# Commands:
#
#   - install [Component] - Install exobrain component?
#   - run [Class]  - Run a given class (presumably inside ubic)
#   - start/stop   - If we provide these, aliases to ubic

my ($command, @args) = @ARGV;

if (not $command) {
    ubic_services();
}
elsif ($command eq "run") {
    my ($class) = @args;
    $class or die "Usage: $0 run class";

    Exobrain->run($class);
}
else {
    # Apparently ubic calls us with service names when it wants
    # to know stuff. So assume that a weird argument is ubic
    # doing its thing
    ubic_services();
    # die "$0: Unknown command: $command @args\n";
}

sub daemon {
    my ($bin) = @_;

    return Ubic::Service::SimpleDaemon->new(
        common_options($bin),
        bin      => $bin,
    );
}

sub agent {
    my ($class) = @_;

    # Start is ourselves, with the start command.
    my @start = ( __FILE__ , "run" );

    my @opts = ( common_options($class), bin => "@start $class" );

    return Ubic::Service::SimpleDaemon->new( @opts );

}

sub common_options {
    my ($name) = @_;

    my $LOG_HOME = "$ENV{HOME}/ubic/log/exobrain";

    return (
        stdout   => "$LOG_HOME/$name.stdout.log",
        stderr   => "$LOG_HOME/$name.stderr.log",
        ubic_log => "$LOG_HOME/$name.ubic.log",
    );
}

sub ubic_services {

    my $config = Exobrain->new->config;
    my @component_services;

    # Load optional components.
    foreach my $component (keys %{ $config->{Components}}) {

        my $class = 'Exobrain::'.$component;

        # Magic component loading dance.
        eval "require $class";
        die $@ if $@;

        my $namespace = $class->component;
        my %services  = $class->services;

        # Map each service into an agent object.
        foreach my $key (keys %services) {
            $services{$key} = agent( $services{$key} );
        }

        # Add these to the things we'll load
        push(@component_services,
            $namespace => Ubic::Multiservice::Simple->new(\%services)
        );
    }

    return Ubic::Multiservice::Simple->new({

        @component_services,

        source => Ubic::Multiservice::Simple->new({
            facebook => daemon("facebook"),
            beeminder => daemon("beeminder-callback"),
            foursquare => daemon("foursquare"),
        }),

        action => Ubic::Multiservice::Simple->new({
            'bee-habit'  => daemon('bee-habit'),
            'bee-inbox'  => daemon('bee-inbox'),
            'rtm-adder'  => daemon('rtm-adder'),
            'sentbox-reward'  => daemon('sentbox-reward'),
            'bee-notify' => daemon('bee-notify'),
            'geo-notify' => daemon('geo-notify'),
            'social-notify' => agent('Action::SocialNotify'),
            'ping'          => agent('Action::Ping'),
            'geo-personallog' => daemon('geo-personallog'),
        }),

        sink => Ubic::Multiservice::Simple->new({
            habitrpg => daemon('habitrpg'),
            beeminder => daemon('beeminder'),
            idonethis => daemon('idone-send'),
            pushover  => daemon('pushover'),
            sms       => daemon('sms'),
        }),

        core => Ubic::Multiservice::Simple->new({
            router => daemon("router"),
        }),
    });
}

__END__

=pod

=head1 NAME

exobrain - UBIC service file for exobrain

=head1 VERSION

version 1.00

=head1 SYNOPSIS

    $ cp `which exobrain` ~/ubic/service
    $ ubic start exobrain

=head1 DESCRIPTION

This is a service file for Ubic which allows for the
control of exobrain services. It must be placed in
your F<~/ubic/service> directory to be operational.

=head1 AUTHOR

Paul Fenwick <pjf@cpan.org>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2014 by Paul Fenwick.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut
