# Copyright (C) 2012, Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
# version 2, as published by the Free Software Foundation.

# This program is distributed in the hope 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, write to the Free Software Foundation, Inc., 59 Temple
# Place - Suite 330, Boston, MA 02111-1307 USA.

################################################################
#
# Module to talk to Jenkins
#
# Add the following lines to BSConfig.pm to enable this plugin
#    our $jenkinsserver = "http://you.jenkins.server.com";
#    our $jenkinsjob = "job/JOB_NAME/buildWithParameters";
#    our $jenkinsnamespace = "OBS";
#    our $notification_plugin = "notify_jenkins";
# Exclude and include rules for filtering events which can trigger Jenkins.
# Regexp pattern fields (project, type etc.) must be alphabetically sorted
# because OBS event string with all attributes gets sorted and then matched.
#    our @excl_patterns = ("project:home:tester:.* type:REPO_PUBLISHED", "project:AnotherProjWeDontWantTriggered:.*");
#    our @incl_patterns = ("project:ImportantProject:.* type:REPO_PUBLISHED", "project:Tizen:.*");

package notify_jenkins;

use BSRPC;
use BSConfig;
use MIME::Base64;
use strict;
use JSON::XS;

sub new {
  my $self = {};
  bless $self, shift;
  return $self;
}

sub pattern_match
{
  my ($event_str, $config_str) = @_;
  my $p;

  print "pattern_match: event_str=[$event_str]\n";
  for $p (@{$config_str}) {
    print "  config_str=[$p]...\n";
    if ($event_str =~ /$p/) {
      return 1;
    }
  }
  return 0;
}

sub notify() {
  my ($self, $type, $paramRef ) = @_;
  my (@event_str, @sorted_event_str, $joined_event_str);
  die('No jenkinssever configured in BSConfig!') unless $BSConfig::jenkinsserver;
  die('No jenkinsjob configured in BSConfig!' ) unless $BSConfig::jenkinsjob;

  my $args = {};

  $type = "UNKNOWN" unless $type;

  @event_str = "type:$type";
  # prepend something BS specific
  my $prefix = $BSConfig::jenkinsnamespace|| "OBS";
  $type =  "${prefix}_$type";
  $args->{'event_type'} = $type;
  if ($paramRef) {
    print "notify: type=[$type]\n";
    for my $key (sort keys %$paramRef) {
      next if ref $paramRef->{$key};
      @event_str = (@event_str , "$key:$paramRef->{$key}");
      print "  key=[$key] value=[$paramRef->{$key}]\n";
      $args->{$key} = $paramRef->{$key} if defined $paramRef->{$key};
    }
    @sorted_event_str = sort @event_str;
    $joined_event_str = join(' ', @sorted_event_str);
    if (@BSConfig::excl_patterns &&
      pattern_match($joined_event_str, \@BSConfig::excl_patterns)) {
      print "notify: excl_pattern returns TRUE, return\n";
      return;
    }
    if (@BSConfig::incl_patterns &&
      !pattern_match($joined_event_str, \@BSConfig::incl_patterns)) {
      print "notify: incl_pattern returns FALSE, return\n";
      return;
    }
  }
  print "notify: ok by filters to trigger Jenkins\n";
  my $jenkinsuri = "$BSConfig::jenkinsserver/$BSConfig::jenkinsjob";
  my $param = {
    'request' => 'POST',
    'uri' => $jenkinsuri,
    'timeout' => 60,
    'maxredirects' => 1,
  };

  my $project;
  if (defined $args->{'project'}){
      $project = $args->{'project'};
  }
  elsif (defined $args->{'targetproject'}) {
      $project = $args->{'targetproject'};
  }else{
      warn("No project name found in events");
      return;
  }

  my @para = ("project=$project",
              "event_type=$type",
              "para=" . encode_base64(encode_json($args),''));
  print "notify: trigger Jenkins uri=[$jenkinsuri] para=[@para]\n";
  eval {
    BSRPC::rpc( $param, undef, @para );
  };
  warn("Jenkins: $@") if $@;
}

1;
