#!/usr/local/bin/perl

#
# Copyright (c) 2002-2004 Eric Wallengren
# This file is part of the Continuous Automated Build and Integration
# Environment (CABIE)
#
# CABIE is distributed under the terms of the GNU General Public
# License version 2 or any later version.  See the file COPYING for copying
# permission or http://www.gnu.org.
#
# THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED OR
# IMPLIED, without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE.  ANY USE IS AT YOUR OWN RISK.
#
# Permission to modify the code and to distribute modified code is granted,
# provided the above notices are retained, and a notice that the code was
# modified is included with the above copyright notice.
#

#
# use packages...
#
#use strict;
#no strict "refs";
use CGI qw(:all);
use Sys::Hostname;

my $POSIX = 1;
my $hostname = hostname();
my $ostype;

if ($ =~ /MSWin32/) {
    $POSIX = 0;
    $ostype = "winsys";
} else {
    $ostype = "unixsys";
}

BEGIN {push @INC, "./lib";}

require "$ostype.pm";
require "$hostname.pm";
use cmbroker;

#
# Create an instance of CGI
#
my $query     = new CGI;
my $initquery = new CGI;

#
# Create instances of packages...
#
my $config   = new $hostname;
my $os       = new $ostype;
my $cmbroker = new cmbroker;

#
# Use for seeing if a job has exists
#
# OS SPECIFIC
my $Moutdir    = $config->JOBDIR;

#
# Get all icons
#
my $disicon    = $config->DISICON;
my $cgibin     = $config->CGIBIN;
my $logo       = $config->LOGOICON;
my $greenicon  = $config->GREENICON;
my $redicon    = $config->REDICON;
my $yellowicon = $config->YELLOWICON;
my $greenicon  = $config->GREENICON;
my $runicon    = $config->RUNICON;
my $promoicon  = $config->PROMOICON;
my $infoicon   = $config->INFOICON;
my $webserver  = $config->WEBSERVER;
my $cgibin     = $config->CGIBIN;
my $bugdb      = $config->BUGDB;

my @sservers;
my @sjobs;
my @jobnos;
my @output;

#
# Global values for fields...
#
my $Server;
my $HServer;
my $Title;
my $HTitle;
my $Port;
my $Client;
my $Root;
my $Type;
my $Tools;
my $Keep;
my $Comment;
my $SCCS;
my $Browser;
my $State;
my $Query;

my $LastServer;
my $LastTitle;

#
# Colors used for genweb
#
my @colors = qw (
    33cc99
    dc1973
    FE5066
    b9ffb9
);
my @colorsa = qw (
    b9ffb9
    ff6600
    fe5066
);

my $nullpattern = "";
my $Prompt="<td class=\"top_toolbar\" bgcolor=\"#CCCCCC\" nowrap>&nbsp;Generate changed file list for selected builds</td>";

#
# Get the time...
#
my $now      = time();

my $rightnow = _gen_time_string($now, 0);

my $debug = 1;
my $string;

if ($debug) {
    open (DBG, ">/tmp/debug.out");
}

#
# Populate jobhash...
#
_get_job_info();

#
# Print content-type info
#
print "Content-type: text/html\n\n";

#
# Print standard information...
#
print <<EOF;
<html>
<head>
<link REL="SHORTCUT ICON" HREF="$logo">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<link rel="stylesheet" href="/main/static/style/bims.css" type="text/css">
<!-- #BeginEditable "head" --> 
<!-- This area is for individual DreamWeaver pages to add to -->
<!-- #EndEditable -->
<STYLE>
  .bulle
  {
    position : absolute;
    visibility : hidden;
  }
</STYLE>
<title> -- CABIE Build Job Information</title>
</head>
<body bgcolor=\"#f0f0f0\">
<DIV CLASS=bulle id=topdeck></DIV>

<SCRIPT>

var ns = (document.layers); 
var ie = (document.all);
var skn = (ns) ? document.topdeck : topdeck.style;
if (ns) document.captureEvents(Event.MOUSEMOVE);
document.onmousemove = get_mouse;

function nothing()
{

}

function pop(texte,fond,title) 
{

  var msg  = "";
  var ttle = "";
  var line = "";
  msg      = texte;
  ttle     = title;
  
  line ="<TABLE BORDER=0 CELLPADDING=1 CELLSPACING=0 BGCOLOR=#352F7F><TR><TD><TABLE WIDTH=100% BORDER=0 CELLPADDING=0 CELLSPACING=0><TR><TD><CENTER><FONT FACE='ARIAL' COLOR=#FFFFFF SIZE=2><B>"+ttle+"</B></FONT></CENTER></TD></TR></TABLE><TABLE WIDTH=100% BORDER=0 CELLPADDING=2 CELLSPACING=0 BGCOLOR="+fond+"><TR><TD><FONT COLOR=#000000 SIZE=1 face=Verdana>"+msg+"</TD></TR></TABLE></TD></TR></TABLE>";

  if (ns) 
  { 
    skn.document.write(line); 
	  skn.document.close();
	  skn.visibility = "visible";
  }
    else if (ie) 
  {
	  document.all("topdeck").innerHTML = line;
	  skn.visibility = "visible";  
  } else
  {
	  document.all("topdeck").innerHTML = line;
	  skn.visibility = "visible";  
  }
}

function get_mouse(e) 
{
	var x = (ns) ? e.pageX : event.x+document.body.scrollLeft; 
	var y = (ns) ? e.pageY : event.y+document.body.scrollTop;

	skn.left = x - 60 + 8*Math.random();
        skn.top  = y+20 + 8*Math.random();
}

function kill() 
{
  skn.visibility = "hidden";
}

</SCRIPT>

<table width='100%' border='0' cellpadding='0' cellspacing='0'>
<tr>
<td rowspan='2'>
<img src=\"$logo\" alt=\"LOGO\" align=middle>
</td>
<td valign="bottom" align="right">
<font color=#000077>
<h2>CABIE - Build Job Information&nbsp;</h2>
</font>
</td>
</tr>
</table>
<br>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td bgcolor="#000000"><img src="/main/static/images/pixel.gif" width="1" height="1"></td>
</tr>
</table>
<table width="100%" border="0" cellspacing="0" cellpadding="2">
<tr>
$Prompt
</tr>
</table>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td bgcolor="#000000"><img src="/main/static/images/pixel.gif" width="1" height="1"></td>
</tr>
</table>
<br>
<hr>
EOF

&gen_values($query);

#
# Create job array...
#
foreach $entry (keys %jobhash) {
    push @jobs, $entry;
}

#
# Create server array...
#
foreach $entry (keys %servhash) {
    push @servers, $entry;
}

#
# The main function for rendering job data in a table.
#
&do_work($query);

#
# Generate a form to create a CGI query
#
&print_prompts($query);

#
# Print end of document.
#
print <<EOF;

<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td bgcolor="#000000"><img src="/main/static/images/pixel.gif" width="1" height="1"></td>
</tr>
</table>
<table width="100%" border="0" cellspacing="0" cellpadding="2">
<tr> 
<td class="bottom_toolbar" bgcolor="#CCCCCC">&nbsp;&nbsp;</td>
<td class="bottom_toolbar" align="right" bgcolor="#CCCCCC"><span class="text_disabled">
    CABIE</a></span> Copyright &copy; 2002 
<script language="JavaScript">
 var date = new Date();
 var year = date.getFullYear();
 if ( year > 2002 ) document.write( " - " + year );
</script> Eric Wallengren&nbsp;&nbsp;</td>
</tr>
</table>
<table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td bgcolor="#000000"><img src="/main/static/images/pixel.gif" width="1" height="1"></td>
</tr>
</table>
</body>
</html>
EOF

#
# Close file if debugging is on
if ($debug) {
    close(DBG);
}

#
# Generate a form for presentation to the user.
#
sub print_prompts {

    #
    # We need to use this instance of CGI
    #
    my ($query) = @_;

    $Query   = $query->param('Query');
    #
    # Print breaks
    #
    print "<br>\n".
          "<br>\n";

    #
    # Setup a form, and a table withing the form
    #
    #
    # Setup a form, and a table withing the form
    #
    if ($Server =~ /^$/ || $Title =~ /^$/ ) {

    print $query->start_form(-method=>'GET');
    print $query->table({-border=>1},

        #
        # We want to display fields here
        #
        Tr({-align=>LEFT, -valign=>TOP},
        [
            th(['Server', 'Title', 'Information']),
            td(
               [

               $query->scrolling_list(-name=>'srvr',
                                      -values=>[sort @servers],
                                      -default=>"$Server",
                                      -size=>'10',
                                      -multiple=>'false'),

               $query->scrolling_list(-name=>'title',
                                      -values=>[sort @jobs],
                                      -default=>"$Title",
                                      -size=>'10',
                                      -multiple=>'false'),

               p('Select Server, and Title then click on 
                  <b>Submit</b> to get a list of job numbers.')
               ]
             ),
        ]
        )
    );
    } else {

        if (@output > 10) {
            foreach $line (reverse @output) {
                print $line;
            }
        }

        print $query->start_form(-method=>'GET');
    
        print $query->table({-border=>1},
    
            # 
            # We want to display fields here 
            #
            Tr({-align=>LEFT, -valign=>TOP},
            [
                th(['Server', 'Title', 'Starting Job', 'Ending Job', 'Information']), 
                td(
                   [
    
                   $query->scrolling_list(-name=>'srvr',
                                          -values=>[sort @servers],
                                          -default=>"$Server",
                                          -size=>'10',
                                          -multiple=>'false'),
    
                   $query->scrolling_list(-name=>'title',
                                          -values=>[sort @jobs],
                                          -default=>"$Title",
                                          -size=>'10',
                                          -multiple=>'false'),
    
                   $query->scrolling_list(-name=>'startjob',
                                          -values=>[@jobnos],
                                          -size=>'10',
                                          -multiple=>'false'),
    
                   $query->scrolling_list(-name=>'endjob',
                                          -values=>[@jobnos],
                                          -size=>'10',
                                          -multiple=>'false'),

                   p('Select the <b>Starting Job</b>, then 
                      <b>Ending Job</b> and click on <b>Generate 
                      List</b>.  The list presented will contain 
                      the job number from the build server, 
                      the user, version and files changed in the 
                      selected build or selected range of builds.  
                      All files will be hypertext linked to the browser 
                      associated with the job selected.'),
    
                   ]
                )
            ]
            ),

        );

        print $query->hidden(-name=>'hsrvr',
                       -default=>"$Server");
        print $query->hidden(-name=>'htitle',
                       -default=>"$Title");
        print $query->hidden(-name=>'sortby',
                       -default=>"job");
    

        if ($Query =~ /^Submit$/ ) {
            open (PARAMS, ">/tmp/save");
            $query->save(PARAMS);
            close(PARAMS);
        }
    }

    print "<br><hr>";

    #
    # Create the submit mechanism
    #
    if ($Server =~ /^$/ || $Title =~ /^$/ ) {
        print $query->submit(-name=>'Query',
                             -value=>'Submit');
    } else {
        print $query->submit(-name=>'Query',
                             -value=>'Generate List');
    }


    #
    # End the form
    #
    print end_form;

}

sub do_work {

    my($query) = @_;

    my @hasharray;
    my @emptyhash;

    #
    # Use from a CGI POST
    #
    $Server  = $query->param('srvr');
    $Title   = $query->param('title');
    $Query   = $query->param('Query');
    $Start   = $query->param('startjob');
    $End     = $query->param('endjob');
    $Sortby  = $query->param('sortby');

    if ($Query =~ /^Submit$/ ) {

        #
        # Grab server, and titles from configuration table
        #
        $sqlquery = "select job from jobs where binary server=\"$Server\" ".
                    "and binary title=\"$Title\" order by job desc";
        @jobnos   = $os->run_sql_query("$sqlquery", ";", 0);
    
    } else {

        #
        # Grab server, and titles from configuration table
        #
        $sqlquery = "select job from jobs where binary server=\"$Server\" ".
                    "and binary title=\"$Title\" order by job desc";
        @jobnos    = $os->run_sql_query("$sqlquery", ";", 0);
        if (defined($Start)) {
            $browse = _genbrowserstring($Server, $Title);
            @output = _genchangelist($Server, $Title, $browse, $Start, 
                                     $End, $Sortby);
        }

    }

}

#
# Get parameters from a 'POST'
#
sub gen_values {

    my ($query) = @_;

    my @emptyarray;

    @sservers = @emptyarray;
    @sjobs    = @emptyarray;

    #
    # read servers and jobs 
    #
    @sservers = $query->param('servers');
    @sjobs    = $query->param('jobs');

}

#
# Generate readable time string from perl's 'time' function
#
sub _gen_time_string {

    my $ts   = shift;
    my $arg  = shift;

    my $returnstring;

    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = 
        localtime($ts);

    if ($arg == 1) {
        $returnstring = sprintf("%02d/%02d/%04d\@%02d:%02d:%02d\n", $mon+1, 
            $mday, 1900 + $year, $hour, $min, $sec);
    } else {
        $returnstring = sprintf("%02d/%02d/%04d %02d:%02d:%02d\n", $mon+1, 
            $mday, 1900 + $year, $hour, $min, $sec);
    }

    return $returnstring;

}

#
# Get a list of all active jobs from the configuration table
# and assign the output to global hashes...
#
sub _get_job_info {

    #
    # Local vars
    #
    my $sqlquery;
    my @sqlret;
    my $line;

    #
    # Grab server, and titles from configuration table
    #
    $sqlquery  = "select server, title from configuration";
    @sqlret    = $os->run_sql_query("$sqlquery", ":", 0);

    #
    # Assign unique identifiers to all hashes...
    #
    foreach $line (@sqlret) {
        $mservjobhash{$line} = "";
        my ($server, $title) = split(/:/, $line);
        $servhash{$server} = "";
        $jobhash{$title} = "";

        #
        # Create the master server/job hash using a unique identifier
        # assign 0 to use later in skipline counter (maybe).
        #
        # $servjobhash{"$server:$title"} = 0;
    }

    #
    # Assign master hash to multiple hashes for use later
    #
    %idlehash  = %servjobhash;
    %statehash = %servjobhash;

} 

#
# Debug routine...
#
sub _debug {

    my $line = shift;

    if ($debug) {
        print DBG "$line\n";
    }
}

sub _do_popup {

    my $string = shift;
    my $title  = shift;
    chomp $string;
    chomp $title;

    $string =~ s/\n/\<br\>/g;

    return "onmouseout=kill(); onmouseover=\"pop(\'<font size=1>$string".
           "</font>\','#B3AFE9',\'$title\'); return true\"";

}

sub _genchangelist {

    my $server    = shift;
    my $title     = shift;
    my $browser   = shift;
    my $startjob  = shift;
    my $endjob    = shift;
    my $sortby    = shift;
    my @sortarray;

    my $sqlquery;
    my @sqlarray;
    my @return;
    my $line;
    my $previous;
    my $previousmail;
    my $previousjob;
    my $alter = 1;
    my $numrec = 2;
    my $jobrows = 1;
    my $whorows = 1;
    my $bugrows = 1;
    my $sstringn = "None logged";

    my $fileformatted;

    my $sccs;

    my $thesccs;
    my $thebl;

    if (!defined($server) || !defined($title) || !defined($browser) 
        || !defined($startjob)){
        push @sqlarray, "invalid args for _genchangelist";
        return @sqlarray;
    }

    $sccs = _returnsccs($server, $title);

    if (!defined($endjob)) {
        $endjob = $startjob;
    }

    push @sortarray, $startjob;
    push @sortarray, $endjob;

    if ($sortarray[0] > $sortarray[1]) {
        $endjob   = $sortarray[0];
        $startjob = $sortarray[1];
    } else {
        $endjob   = $sortarray[1];
        $startjob = $sortarray[0];
    }


    if (defined($endjob)) {
        $sqlquery = "select job,changes from changes where ".
                    "binary server=\"$server\" and binary ".
                    "title=\"$title\" and binary job >=\"$startjob\" and ".
                    "binary job <=\"$endjob\" order by $sortby";
    } else {
        $sqlquery = "select changes from changes where ".
                    "binary server=\"$server\" and binary ".
                    "title=\"$title\" and job=\"$startjob\" order by $sortby";
    }

    @sqlarray  = $os->run_sql_query("$sqlquery", ",", 0);

    my $recsavail = @sqlarray;

    push @return, "<p>\n";

    if ($recsavail > 0) {

        my $l;
    
        push @return, "</table>";
        
        for ($l = 0; $l < @sqlarray; $l++) {
        
            $sstring = "";
            $sstringn = "";
            my ($job, $info) = split(/,/, $sqlarray[$l]);
            my ($jobn, $infon) = split(/,/, $sqlarray[$l+1]);
            my ($file, $ver, $date, $who) = split(/;/, $info);
            my ($filen, $vern, $daten, $whon) = split(/;/, $infon);
       
            my $fooquery = "select sccs, browserlink, port from jobs where ".
                           "binary server=\"$server\" and binary ".
                           "title=\"$title\" and job=\"$job\"";
    
            my @fooarray = $os->run_sql_query($fooquery, ",");
    
            ($thesccs, $thebl, $port) = split(/,/,$fooarray[0]);
      
            $sccscommand = $thesccs."_formaturl";

            $urlreturn = $cmbroker->$sccscommand($file, $ver, $thebl, $port);

            $fileformatted = sprintf("<a href=$urlreturn>%s</a>", $file);

            #
            # Get users from CM broker
            #
            $sccscommand = $sccs."_useraddress";

            $fulladdress = $cmbroker->$sccscommand($who, $port);

            ($useraddress, $username) = split(/:/, $fulladdress);

            $mailform  = sprintf ("<a href=mailto:%s>$username</a>", 
                                  $useraddress);

            $sqlquery  = "select comment from comments where binary ".
                         "server=\"$server\" and binary title=\"$title\" ".
                         "and job=\"$job\"";
    
            $sqlqueryn = "select comment from comments where binary ".
                         "server=\"$server\" and binary title=\"$title\" ".
                         "and job=\"$jobn\"";
    
            my @nsqlarray  = $os->run_sql_query("$sqlquery", ",", 0);
            my @nsqlarrayn = $os->run_sql_query("$sqlqueryn", ",", 0);
    
            if (@nsqlarray > 0) {
                $sstring = $nsqlarray[0];
                $sstring =~ s/Defects fixed in this build\://g;
            } else {
                $sstring = "None logged.";
            }
    
            if (@nsqlarrayn > 0) {
                $sstringn = $nsqlarrayn[0];
                $sstringn =~ s/Defects fixed in this build\://g;
            } else {
                if ($l + 2 > @sqlarray) {
                    $sstringn = "Done";
                } else {
                    $sstringn = "None logged.";
                }
            }
    
            chomp $sstring;
            chomp $sstringn;
    
            push @return, "</tr>\n";
    
            $thestring = _createlinks("$sstring");
            $thestringn = _createlinks("$sstringn");
    
            if ("$previous" ne "$sstring") {
                if($thestring ne $thestringn) {
                    push @return, "<td align=left valign=top width=100 ".
                                  "rowspan=$bugrows bgcolor=#dddddd>".
                                  "$thestring</td>\n";
                    $bugrows=1;
                    $previous = $sstring;
                } else {
                    $bugrows++;
                }
            } else {
                $sstring = "";
                $bugrows++;
            }
    
            push @return, "<td align=left width=100 bgcolor=#dddddd>".
                          "$fileformatted</td>\n";
            push @return, "<td align=left width=100 bgcolor=#dddddd>".
                          "$ver</td>\n";
    
            if ("$previousmail" eq "$mailform") {
                $whorows++;
            } else {
                if ($who ne $whon) {
                    push @return, "<td align=center valign=top width=100 ".
                                  "rowspan=$whorows bgcolor=#dddddd>".
                                  "$mailform</td>\n";
                    $whorows=1;
                    $previousmail = $mailform;
                } else {
                    $whorows++;
                }
            }
            if ("$previousjob" eq "$job") {
                $jobrows++;
            } else {
                if ($job ne $jobn) {
    
                    $newq = "select status from jobs where title=\"$title\" ".
                            "and job=\"$job\"";
                    @newary  = $os->run_sql_query("$newq", ",", 0);
                    $st = $newary[0];
                    if (-d "/mnt/dev/builds/$title/$job") {
                        push @return, "<td align=left valign=top width=100 ".
                                      "rowspan=$jobrows bgcolor=#$colors[$st]>".
                                      "<a href=\"$webserver/$title/$job\">".
                                      "$job</a></td>\n";
                        $jobrows=1;
                    } else { 
                        push @return, "<td align=left valign=top width=100 ".
                                      "rowspan=$jobrows bgcolor=#$colors[$st]>".
                                      "$job</td>\n";
                        $jobrows=1;
                    }
                    $previousjob = $job;
                } else {
                    $jobrows++;
                }
            }
            push @return, "<tr>\n";
        }
    
        push @return, "<b>Defects</b>\n</td>";
        push @return, "<td align=left width=100 bgcolor=#aaaaff>";
        push @return, "<b><a href=\"/cgi-bin/listchanges?srvr=$server&title=".
                      "$title&startjob=$startjob&endjob=$endjob&hsrvr=".
                      "$server&htitle=$title&sortby=changes&Query=".
                      "Generate+List\">File</a></b>\n</td>";
        push @return, "<td align=left width=100 bgcolor=#aaaaff>";
        push @return, "<b>Version</b>\n</td>";
        push @return, "<td align=left width=100 bgcolor=#aaaaff>";
        push @return, "<b>User</b>\n</td>";
        push @return, "<td align=left width=100 bgcolor=#aaaaff>";
        push @return, "<b><a href=\"/cgi-bin/listchanges?srvr=$server&title=".
                      "$title&startjob=$startjob&endjob=$endjob&hsrvr=".
                      "$server&htitle=$title&sortby=job&Query=Generate+List\"".
                      ">Job Number</a></b>\n</td>";
        push @return, "<td align=left width=100 bgcolor=#aaaaff>";
        push @return, "<table frame=box cellSpacing=1 cellPadding=2 ".
                      "border=1>\n<tr>\n";

    }
        
    return @return;
        
}
        
sub _createlinks {

    my $string     = shift;
    my $origstring = $string;

    $string =~ s/\,/ /g;
    #$string =~ s/\./ /g;
    $string =~ s/\[//g;
    $string =~ s/\].//g;
    $string =~ s/\]//g;
    $string =~ s/\s/ /g;

    @array = split(/ /, $string) ;

    foreach $line (@array) {
        if ($line !~ /\./) {
            if ($line > 0) {
                $replace = sprintf("<a href=\"$bugdb\">%s</a>", $line, $line);
                if ($replace !~ /\-1/) {
                $origstring =~ s/$line/$replace/g;
                $origstring =~ s/\n$line/$replace/g;
                }
            }
        }
    }

    return "$origstring";

}

sub _genbrowserstring {

    my $server = shift;
    my $title  = shift;
    my $sqlquery;
    my @sqlarray;

    if (!defined($server) || !defined($title)) {
        push @sqlarray, "invalid args for _genjoblist";
        return $sqlarray[0];
    }

    $sqlquery = "select browserlink from configuration where binary ".
                "server=\"$server\" and binary title=\"$title\"";

    @sqlarray  = $os->run_sql_query("$sqlquery", ";", 0);

    if (@sqlarray == 0) {
        push @sqlarray, "no records found: $server $title";
    }

    return $sqlarray[0];

}

sub _returnsccs {

    my $server = shift;
    my $title  = shift;

    my @sqlarray;
    my $sqlquery;

    $sqlquery = "select sccs from configuration where binary ".
                "server=\"$server\" and binary title=\"$title\"";

    @sqlarray  = $os->run_sql_query("$sqlquery", ";", 0);

    if (@sqlarray == 0) {
        push @sqlarray, "no records found: $server $title";
    }

    return $sqlarray[0];

}
