#!/usr/bin/perl
#
# cpanel - cp_util/bamboo/generate-bamboo-cookie.pl
#                                                 Copyright(c) 2015 cPanel, Inc.
#                                                           All rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
#
###################################################################################
#
# This script is executed by Bamboo.  It is used to tell vmware-manager to kick
# off a new build.
#
# If this script isn't working, then make sure the HTTP cookie this script uses
# to log into vmware-manager hasn't expired.  If you're not sure, simply execute
# generate-bamboo-cookie.pl and follow its instructions.
#
# This script requires that you enter two environment plan variables within Bamboo.
#  - BuildCookie
#  - BuildProject
#
# Variable: BuildCookie:
#   This is generated by executing generate-bamboo-cookie.pl.  Once it's created,
#   log into Bamboo, go to your Plan Configuration, and select the 'Variables' tab.
#   Then add this variable name, and the output of generate-bamboo-cookie.pl as
#   the value.
#
# Variable: BuildProject:
#   This variable is needed to that it knows which build to kick off on
#   vmware-manager.
###################################################################################

use strict;
use warnings;
use Data::Dumper;
use JSON           ();
use HTTP::Cookies  ();
use WWW::Mechanize ();

my $DIRECTION = q{Run cp_util/bamboo/generate-bamboo-cookie.pl and follow instructions};
my $SERVER    = q{vmware-manager.dev.cpanel.net};

my $COOKIE_KEY = q{BuildCookie};     # JSON string generated by generate-bamboo-cookie.pl that's used to log into vmware-manager
my $BUILD_KEY  = q{BuildProject};    # Project name we want to build

sub queue_build {
    my $args  = shift;
    my $agent = q{ea3/generate-dev-build.pl};
    my $mech  = WWW::Mechanize->new( keep_alive => 1, autocheck => 1, agent => $agent, cookie_jar => $args->{$COOKIE_KEY} );

    # load the queue a build page
    my $url = qq{http://$SERVER/vm/cppack/branchbuild};
    $mech->get($url);

    # make sure we're actually on the queue a build page
    unless ( $mech->content() =~ /Select\s+a\s+project\s+to\s+check\s+and\s+build/i ) {
        die "ERROR: generate-bamboo-cookie failed to load $url (This could be due to an expired/bad cookie or the page content changed)";
    }

    # make sure the publish_target form is present
    my $form = $mech->form_name('publish_target');
    die "ERROR: Failed to find the 'publish_target' form to queue a build at $url" unless $form;

    # the publish_target form has a drop-down menu with name 'project'
    my $input = $form->find_input( 'project', 'option' );
    die "ERROR: Failed to find the 'project' drop-down menu at $url" unless $input;

    # validate the project requested exists in the drop-down menu
    my @projects = $input->possible_values();
    die "ERROR: Failed to find project '$args->{$BUILD_KEY}' in project list at $url" unless grep( /\A$args->{$BUILD_KEY}\z/, @projects );

    # the project exists, so select it
    unless ( $mech->select( 'project', [ $args->{$BUILD_KEY} ] ) ) {
        die "ERROR: Failed to find the $args->{$BUILD_KEY} project at $url";
    }

    # queue the build
    $mech->submit();

    # and make sure we could queue the build successfully
    my $html = $mech->content();
    unless ( $html =~ /Job\s+'(.*?)'\s+has\s+been\s+added/i ) {
        my $msg = "Failed to queue $args->{$BUILD_KEY} project at $url:\n";

        if ( $html =~ /Result:.+<pre>.+Error:(.+?)<\/pre>/ms ) {
            $msg .= "\n$1\n";
        }
        else {
            $msg .= "\nNo error message found\n";
        }

        die "ERROR: $msg";
    }

    print "SUCCESS: Queued build: $1\n";

    return 1;
}

sub get_args {
    my %args;

    die "ERROR: This should only be run by Bamboo" unless defined $ENV{bamboo_agentId};

    # acquire http::cookie for later
    my $key = qq{bamboo_$COOKIE_KEY};
    die "ERROR: $DIRECTION" unless $ENV{$key};
    my $json_cookie = eval { JSON::decode_json( $ENV{$key} ) };
    die "ERROR: $COOKIE_KEY contains invalid JSON.  $DIRECTION" if $@;
    my $cookie = HTTP::Cookies->new();
    my $c      = $cookie->set_cookie(@$json_cookie);
    die "ERROR: $COOKIE_KEY is not a valid HTTP::Cookie.  $DIRECTION" unless $c->as_string();
    $args{$COOKIE_KEY} = $cookie;

    # get project
    $key = qq{bamboo_$BUILD_KEY};
    die "ERROR: You must add $BUILD_KEY as a Plan Variable" unless $ENV{$key};
    $args{$BUILD_KEY} = $ENV{$key};

    return \%args;
}

my $args = get_args();
queue_build($args);
exit 0;

