package NGCP::Gather::SIPOption 0.001;
##
# Check the responsiveness of a SIP server.
#
# Copyright © 2005-2006 O'Shaughnessy Evans <shaug+nagios@aloha.net>
# Copyright © 2011, 2015--2017 Sipwise GmbH, Austria
#
# Requires sipsak; see sipsak.org for more info.
##

use strict;
use warnings;

our @EXPORT = qw(
    check_sip_option
);

use Exporter qw(import);
use Carp;

=encoding utf8

=head1 NAME

NGCP::Gather::SIPOption - Gather SIP OPTION information

=head1 DESCRIPTION

This module provides support functions to gather SIP OPTION information.
for monitoring purposes.

=head1 FUNCTIONS

=over 4

=item $cert = check_sip_option(%opts)

Get the SIP OPTION duration within the specified thresholds, and any error
condition found.

=cut

sub check_sip_option
{
    my (%opts) = @_;

    $opts{verbose} //= 0;
    $opts{proxy} //= '';
    # Use a local port in 6000 <= port < 10000.
    $opts{local_port} //= int(rand(4000) + 6000);
    $opts{warn_threshold} //= 1;
    $opts{crit_threshold} //= 5;

    # Command to get connection state.
    my @cmd = qw(/usr/bin/sipsak --nagios-code -v -D 5);

    if (!$opts{uri}) {
        croak "ERROR: needs full URI";
    }

    # Add -v flags to sipsak according to the verbosity level passed.
    push @cmd, '-vv';
    foreach (1 .. $opts{verbose}) {
        push @cmd, '-v';
    }

    # Add a proxy to the sipsak command line if one was given.
    if ($opts{proxy}) {
        push @cmd, '--outbound-proxy', $opts{proxy};
    }

    push @cmd, '--local-port', $opts{local_port};
    push @cmd, '--symmetric';

    push @cmd, '--sip-uri', $opts{uri};
    print "executing:  ". join(' ', @cmd) . "\n" if $opts{verbose};
    my $cmd = join(' ', @cmd);
    my @out = qx($cmd 2>&1);
    print "output is:\n\n@out\n" if $opts{verbose};
    chomp @out;

    my ($status) = grep { /^SIP\s/ } @out;
    chomp $status;

    my %res;
    if ($status =~ /^SIP(\/[\d.]+ 2\d\d)? OK/i) {
        $res{ok} = 1;
        foreach my $line (@out) {
            my ($duration) = $line =~ /reply received after (.+) ms/;

            if ($duration) {
                $res{duration} = sprintf("%.03f", $duration / 1000.0);
                last;
            }
        }

        if (not defined $res{duration}) {
            $res{state} = 'unknown';
            $res{answer} = 'No duration found';
        } elsif ($res{duration} > $opts{crit_threshold}) {
            $res{state} = 'critical';
            $res{answer} = 'Critical duration threshold exceeded';
        } elsif ($res{duration} > $opts{warn_threshold}) {
            $res{state} = 'warning';
            $res{answer} = 'Warning duration threshold exceeded';
        } else {
            $res{state} = 'ok';
            $res{answer} = $status;
        }
    } else {
        $res{ok} = 0;
        $res{state} = 'critical';
        $res{answer} = "$status (\"...$out[-2]\")";
    }
    return \%res;
}

=back

=head1 CHANGES

=head2 Version 0.xxx

This is a private module.

=head1 AUTHOR

Guillem Jover <gjover@sipwise.com>

=head1 BUGS

Please report any bugs to Sipwise GmbH.

=head1 LICENSE

Copyright (C) 2020-2022 Sipwise GmbH, Austria

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.

=cut

1;
