#!/usr/bin/perl -w
# --
# Changed Version of Generic Agent that is used for closing
# Tickets and adding Notes to Tickets
# --

#
# USAGE: GaCloseNagiosTickets.pl -h HOST -S SERVICE -s STATUS -m MESSAGE -c CLOSE
#
# if close = 1 then Ticket will be closed, otherwise a note will be added
#

# use ../ as lib location
use File::Basename;
use FindBin qw($RealBin);
use lib dirname($RealBin);
use lib dirname($RealBin)."/Kernel/cpan-lib";

use strict;

use vars qw($VERSION $Debug $Limit);

use Getopt::Std;
use Kernel::Config;
use Kernel::System::Log;
use Kernel::System::DB;
use Kernel::System::Ticket;
use Kernel::System::Queue;

# configuration

my @nagios_queues = ['nagios_test', 'nagios_test::or', 'nagios_test::krz', 'nagios_test::ti', 'nagios_test::or4'];
# Definitions for TicketFreeKeys and TicketFreeText
# (use the same settings in NagiosGenericAgent.pl !!)
# definitions for host freefield
my $host_key            = "X-OTRS-TicketKey2";          # TicketFreeKey
my $host_text           = "X-OTRS-TicketValue2";        # TicketFreeText
my $host_name           = "Server";                     # Value for TicketFreeKey
# definitions for service freefield
my $service_key         = "X-OTRS-TicketKey4";          # TicketFreeKey
my $service_text        = "X-OTRS-TicketValue4";        # TicketFreeText
my $service_name        = "Service";                    # Value for TicketFreeKey
# definitions for state freefield
my $state_key           = "X-OTRS-TicketKey3";          # TicketFreeKey
my $state_text          = "X-OTRS-TicketValue3";        # TicketFreeText
my $host_state_name     = "Server-Status";              # Value for TicketFreeKey (State of the Host)
my $service_state_name  = "Service-Status";             # Value for TicketFreeKey (State of the Service)

# subjects
my $subject_close 	= "NAGIOS: Problem ist behoben!";	# e.g. "Nagios: Problem solved"
my $subject_note	= "NAGIOS: Problem besteht weiterhin!"; # e.g. "Nagios: Problem still exists"

# article type for notes
my $article_type 	= 'note-internal'; # note-internal|note-external|note-report

# from
my $from 		= "NAGIOS";

# end of configuration

my %Opts = ();
getopt('hSscaoNCT', \%Opts);
my $HOST 	= $Opts{'h'};
my $SERVICE	= $Opts{'S'};
my $STATUS 	= $Opts{'s'};
my $CLOSE	= $Opts{'c'} || 0;
my $NT 		= $Opts{'N'} || "";
my $AD 		= $Opts{'a'} || "";
my $OUT 	= $Opts{'o'} || "";
my $CONTACT 	= $Opts{'C'} || "";
my $TYPE 	= $Opts{'T'};

if (!$HOST || !$SERVICE || !$STATUS || !$TYPE){
	print "\nAt least a HOST, SERVICE, TYPE and STATUS must be provided!\n";
	exit(1);
}

# translate this if you like
my $MESSAGE =   "Art der Meldung: $NT\n".	# notificationtype
                "Service: $SERVICE\n".		# service
                "Servername: $HOST ($AD)\n".	# host (address)
                "Status: $STATUS\n\n".		# state
                "Ausgabe: $OUT";		# output

my $statefield = $service_state_name;
if ($TYPE eq "h"){ $statefield = $host_state_name; }
my $ticketstate="";
my $ticketsubject="";
if ($CLOSE){
  $ticketstate = "closed successful";
  $ticketsubject = $subject_close;
}else{
  $ticketstate = "open";
  $ticketsubject = $subject_note;
}

#
# Create Job
#
my %Jobs = (
   'nagios_job' => {
	# get all tickets with this properties
	Queue => \@nagios_queues,
	# Match Host
	TicketFreeText2 => $HOST,
	# Match Service
	TicketFreeText3 => $SERVICE,
	New => {
	       Note => {
		       From => $from,
		       Subject => $ticketsubject,
		       Body => $MESSAGE,
		       ArticleType => $article_type,
	       },
		# set new Service/Host-State
		TicketFreeKey4 => $statefield,
		TicketFreeText4 => $STATUS,
		# set new ticketstate
		State => $ticketstate,
	}
   }
);

#####
#
# THE FOLLOWING IS THE NON-CHANGED CODE OF GenericAgent.pl FROM OTRS V. 1.2.2
#
# If you like to use this script with other OTRS Versions maybe you have to 
# replace the code
#
#####

# set generic agent uid
my $UserIDOfGenericAgent = 1;

# common objects
my %CommonObject = ();
$CommonObject{ConfigObject} = Kernel::Config->new();
$CommonObject{LogObject} = Kernel::System::Log->new(
    LogPrefix => 'OTRS-GenericAgent',
    %CommonObject,
);
$CommonObject{DBObject} = Kernel::System::DB->new(%CommonObject);
$CommonObject{TicketObject} = Kernel::System::Ticket->new(
    %CommonObject,
    Debug => $Debug, 
);
$CommonObject{QueueObject} = Kernel::System::Queue->new(%CommonObject);

# --
# process all jobs
# --
foreach my $Job (sort keys %Jobs) {
    print "$Job:\n";
    # --
    # get regular tickets 
    # --
    my %Tickets = ();
    if (! $Jobs{$Job}->{Escalation}) {
        my %PartJobs = %{$Jobs{$Job}};
        if (!$PartJobs{Queue}) {
            print " For all Queues: \n";
            %Tickets = $CommonObject{TicketObject}->SearchTicket(
                %{$Jobs{$Job}},
                Limit => $Limit,
            );
        }
        elsif (ref($PartJobs{Queue}) eq 'ARRAY') {
            foreach (@{$PartJobs{Queue}}) {
                print " For Queue: $_\n";
                %Tickets = ($CommonObject{TicketObject}->SearchTicket(
                    %{$Jobs{$Job}},
                    Queues => [$_],
                    Limit => $Limit,
                ), %Tickets);
            }
        }
        else {
            %Tickets = $CommonObject{TicketObject}->SearchTicket(
                %{$Jobs{$Job}},
                Queues => [$PartJobs{Queue}],
                Limit => $Limit,
            );
        }
    }
    # --
    # escalation tickets
    # --
    else {
        if (! $Jobs{$Job}->{Queue}) {
            my @Tickets = $CommonObject{TicketObject}->GetOverTimeTickets();
            foreach (@Tickets) {
                $Tickets{$_} = $CommonObject{TicketObject}->GetTNOfId(ID => $_); 
            }
        }
        else {
            my @Tickets = $CommonObject{TicketObject}->GetOverTimeTickets();
            foreach (@Tickets) {
                my %Ticket = $CommonObject{TicketObject}->GetTicket(TicketID => $_);
                if ($Ticket{Queue} eq $Jobs{$Job}->{Queue}) {
                    $Tickets{$_} = $Ticket{TicketNumber};
                }
            }
        }
    }
    # --
    # process each ticket 
    # --
    foreach (sort keys %Tickets) {
        Run($Job, $_, $Tickets{$_});
    }
}
# --
# process each ticket 
# --
sub Run {
    my $Job = shift;
    my $TicketID = shift;
    my $TicketNumber = shift;
    print "* $TicketNumber ($TicketID) \n";
    # --
    # move ticket
    # --
    if ($Jobs{$Job}->{New}->{Queue}) {
        print "  - Move Ticket to Queue '$Jobs{$Job}->{New}->{Queue}'\n";
        $CommonObject{TicketObject}->MoveByTicketID(
            QueueID => $CommonObject{QueueObject}->QueueLookup(Queue=>$Jobs{$Job}->{New}->{Queue}, Cache => 1),
            UserID => $UserIDOfGenericAgent,
            TicketID => $TicketID,
        );
    }
    # --
    # add note if wanted
    # --
    if ($Jobs{$Job}->{New}->{Note}->{Body}) {
        print "  - Add note\n";
        $CommonObject{TicketObject}->CreateArticle(
            TicketID => $TicketID,
            ArticleType => $Jobs{$Job}->{New}->{Note}->{ArticleType} || 'note-internal',
            SenderType => 'agent',
            From => $Jobs{$Job}->{New}->{Note}->{From} || 'GenericAgent',
            Subject => $Jobs{$Job}->{New}->{Note}->{Subject} || 'Note',
            Body => $Jobs{$Job}->{New}->{Note}->{Body}, 
            UserID => $UserIDOfGenericAgent,
            HistoryType => 'AddNote',
            HistoryComment => 'Note added.',
        );
    }
    # --   
    # set new state
    # --
    if ($Jobs{$Job}->{New}->{State}) {
        print "  - set state to '$Jobs{$Job}->{New}->{State}'\n";
        $CommonObject{TicketObject}->SetState(
            TicketID => $TicketID,
            UserID => $UserIDOfGenericAgent,
            State => $Jobs{$Job}->{New}->{State}, 
        );
    }
    # --   
    # set customer id and customer user 
    # --
    if ($Jobs{$Job}->{New}->{CustomerID} || $Jobs{$Job}->{New}->{CustomerUserLogin}) {
        if ($Jobs{$Job}->{New}->{CustomerID}) {
            print "  - set customer id to '$Jobs{$Job}->{New}->{CustomerID}'\n";
        }
        if ($Jobs{$Job}->{New}->{CustomerUserLogin}) {
            print "  - set customer user id to '$Jobs{$Job}->{New}->{CustomerUserLogin}'\n";
        }
        $CommonObject{TicketObject}->SetCustomerData(
            TicketID => $TicketID,
            No => $Jobs{$Job}->{New}->{CustomerID} || '',
            User => $Jobs{$Job}->{New}->{CustomerUserLogin} || '',
            UserID => $UserIDOfGenericAgent,
        );
    }
    # --   
    # set new priority 
    # --
    if ($Jobs{$Job}->{New}->{Priority}) {
        print "  - set priority to '$Jobs{$Job}->{New}->{Priority}'\n";
        $CommonObject{TicketObject}->PrioritySet(
            TicketID => $TicketID,
            UserID => $UserIDOfGenericAgent,
            Priority => $Jobs{$Job}->{New}->{Priority}, 
        );
    }
    # --
    # set new owner
    # --
    if ($Jobs{$Job}->{New}->{Owner}) {
        print "  - set owner to '$Jobs{$Job}->{New}->{Owner}'\n";
        $CommonObject{TicketObject}->SetOwner(
            TicketID => $TicketID,
            UserID => $UserIDOfGenericAgent,
            NewUser => $Jobs{$Job}->{New}->{Owner},
        );
    }
    # --
    # set new lock 
    # --
    if ($Jobs{$Job}->{New}->{Lock}) {
        print "  - set lock to '$Jobs{$Job}->{New}->{Lock}'\n";
        $CommonObject{TicketObject}->SetLock(
            TicketID => $TicketID,
            UserID => $UserIDOfGenericAgent,
            Lock => $Jobs{$Job}->{New}->{Lock},
        );
    }
    # --
    # set ticket free text options
    # --
    foreach (1..8) { 
        if ($Jobs{$Job}->{New}->{"TicketFreeKey$_"} || $Jobs{$Job}->{New}->{"TicketFreeText$_"}) {
            my $Key = $Jobs{$Job}->{New}->{"TicketFreeKey$_"} || '';
            my $Value = $Jobs{$Job}->{New}->{"TicketFreeText$_"} || '';
            print "  - set ticket free text to Key: '$Key' Text: '$Value'\n";
            $CommonObject{TicketObject}->SetTicketFreeText(
                TicketID => $TicketID,
                UserID => $UserIDOfGenericAgent,
                Key => $Key,
                Value => $Value,
                Counter => $_,
            );
        }
    }
    # --
    # run module 
    # --
    if ($Jobs{$Job}->{New}->{Module}) {
        print "  - use module ($Jobs{$Job}->{New}->{Module})\n";
        $CommonObject{LogObject}->Log(
            Priority => 'notice',
            Message => "Use module ($Jobs{$Job}->{New}->{Module}) Ticket [$TicketNumber], TicketID [$TicketID].",
        );
        if ($Debug) {
            $CommonObject{LogObject}->Log(
                Priority => 'debug',
                Message => "Try to load module: $Jobs{$Job}->{New}->{Module}!",
            );
        }
        if (eval "require $Jobs{$Job}->{New}->{Module}") {
            my $Object = $Jobs{$Job}->{New}->{Module}->new(
                %CommonObject,
                Debug => $Debug,
            );
            if ($Debug) {
                $CommonObject{LogObject}->Log(
                    Priority => 'debug',
                    Message => "Loaded module: $Jobs{$Job}->{New}->{Module}!",
                );
                $CommonObject{LogObject}->Log(
                    Priority => 'debug',
                    Message => "Run module: $Jobs{$Job}->{New}->{Module}!",
                );
            }
            $Object->Run(TicketID => $TicketID);
        }
        else {
            $CommonObject{LogObject}->Log(
                Priority => 'error',
                Message => "Can't load module: $Jobs{$Job}->{New}->{Module}!",
            );
        }
    }
    # --
    # cmd
    # --
    if ($Jobs{$Job}->{New}->{CMD}) {
        print "  - call cmd ($Jobs{$Job}->{New}->{CMD}) for ticket_id $_\n";
        $CommonObject{LogObject}->Log(
            Priority => 'notice',
            Message => "Execut '$Jobs{$Job}->{New}->{CMD} $TicketNumber $TicketID'.",
        );
        system("$Jobs{$Job}->{New}->{CMD} $TicketNumber $TicketID ");
    }
    # --
    # delete ticket
    # --
    if ($Jobs{$Job}->{New}->{Delete}) {
        print "  - delete ticket_id $TicketID\n";
        $CommonObject{LogObject}->Log(
            Priority => 'notice',
            Message => "Delete Ticket [$TicketNumber], TicketID [$TicketID].",
        );
        $CommonObject{TicketObject}->DeleteTicket(
            UserID => $UserIDOfGenericAgent, 
            TicketID => $TicketID,
        );
    }
}
# --

