<?php
/*******************************************************************************
 * Copyright (c) 2011, 2012 Eclipse Foundation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *    Wayne Beaton (Eclipse Foundation)- initial API and implementation
 *******************************************************************************/

/*
 * This script assumes that it is being included by another script. We
 * assume that the $App variable has already been defined.
 */

require_once(dirname(__FILE__) ."/Project.class.php");
require_once(dirname(__FILE__) ."/Committer.class.php");
require_once(dirname(__FILE__) . "/debug.php");
require_once(dirname(__FILE__) . "/common.php");
trace_file_info(__FILE__);

// require_once($_SERVER['DOCUMENT_ROOT'] . "/eclipse.org-common/system/app.class.php");
// $App = new App();

// $log = new IPLog(array(getProject('eclipse.orion')));
// print_r($log->getContributions());
//
//echo get_trace_html();

class IPLog {
	var $projects;
	var $committers = array();
	var $contributors = null;
	var $trace;
	
	function __construct($projects) {
		$this->projects = $projects;
		$this->trace = trace("IPLog");
	}
	
	function getContributions() {
		if ($this->contributors === null) {
			$this->gatherGitContributions($this->projects);
			$this->gatherBugzillaContributions($this->projects);
		}
		
		uasort($this->contributors, 'contributors_sort_by_name');
		
		return $this->contributors;
	}
	
	/**
	 * Gather any contributions provided through Git for $project. Contributions
	 * are added to the provided array. This function makes a call to the dash
	 * server for each Git repository listed by the project. The script running
	 * on the server provides the data in CSV form.
	 * 
	 * @internal
	 * @param Project $project
	 * @param Contribution[] $contributions
	 */
	function gatherGitContributions(&$projects) {
		global $App;
		$repositories = array();
		foreach($projects as $project) {
			foreach($project->getSourceRepositories() as $repository) {
				if ($repository->getType() != 'git') continue;
				$path = preg_replace('/^\/gitroot\//', '/home/data/git/', $repository->getPath());
				$repositories[$path] = $repository;
			}
		}
	
		/*
		 * Select records from the repository.
		 * 
		 * Note that we only want those records that could possibly be contributed
		 * by a non-committer. Candidate records either have an author that is
		 * different from the committer, or--if they are from projects that use
		 * Gerrit--have a changeId. Note that these records are not necessarily
		 * from non-committers, but they could be.
		 */
		$sql = "
			select 
				repo, ref, committer, author, authorName, size, comment, commitDate as date 
			from gitlogcache 
			where 
				repo in ('" . implode("','", array_keys($repositories)) . "')
				and author not in ('cvs', 'cvs2git')
				and authorName not in ('cvs2svn', 'cvs2git migration')
				and (changeId is not null or (author != committer))";
		$result = $App->dashboard_sql($sql);
		while ($row = mysql_fetch_assoc($result)) {
			$repo = $row['repo'];
			$ref = $row['ref'];
			$committer = strtolower($row['committer']);
			$author = strtolower($row['author']);
			$authorName = $row['authorName'];
			$size = $row['size'] . ' lines';
			$comment = $this->getAbbreviatedGitComment($row['comment']);
			$date = $row['date'];
			
			if ($this->isProjectCommitter($projects, $author, $date)) continue;

			$repository = $repositories[$repo];
			$path = $repository->getLink();
			$link = "$path/commit?id=$ref";
			
			$this->addContribution($author, $authorName, $ref, substr($ref,0,6), $link, $size, $comment);
		}
	}
	
	function getAbbreviatedGitComment($string) {
		$lines = split("\n", $string);
		return $lines[0];	
	}
	
	/**
	 * @internal
	 * @param unknown_type $author
	 * @param unknown_type $name
	 * @param unknown_type $ref
	 * @param unknown_type $id
	 * @param unknown_type $link
	 * @param unknown_type $size
	 * @param unknown_type $comment
	 */
	function addContribution($author, $name, $ref, $id, $link, $size, $comment) {
		$contributor = $this->addContributor($author, $name);
		if (isset($contributor->contributions[$ref]))
		    $contributor->contributions[$ref]->size += $size;
		else
            $contributor->contributions[$ref] = new Contribution($id, $link, $author, $size, $comment);
	}
	
	function addContributor($email, $name) {
		if (!isset($this->contributors[$email])) {
			$this->contributors[$email] = new Contributor($email, $name);
		}		
		return $this->contributors[$email];
	}
	
	/**
	 * @internal
	 * @param unknown_type $projects
	 */
	function gatherBugzillaContributions(&$projects) {
	    foreach($projects as $project) {
	        IPLogBugzillaBuilder::assemble($this, $project);
	    }
	}	    
	
	function isProjectCommitter(&$projects, $author, $date) {
		foreach($projects as $project) {
			$committer = $this->findProjectCommitter($project, $author);
			if (!$committer) continue;
			if ($committer->isCommitter($project->getId(), $date)) return true;
		}
		return false;
	}
	
	/**
	 * Attempt to find a committer on a particular project. The value of
	 * $author may be a committer id, or it could be an email address.
	 * 
	 * @param Project $project
	 * @param string $author
	 * @return Committer|NULL
	 */
	function findProjectCommitter(&$project, $author) {
		if (!isset($this->committers[$project->getId()])) 
			$this->committers[$project->getId()] = getCommittersForProject($project->getId(), false);
		
		foreach($this->committers[$project->getId()] as $committer) {
			if ($committer->id == $author) return $committer;
			if ($committer->hasEmailAddress($author)) return $committer;
		}
		return null;
	}
	
	function getSourceRepositories() {
		$repositories = array();
		foreach($this->projects as $project)
			foreach($project->getSourceRepositories() as $repository)
				$repositories[] = $repository;
		return $repositories;
	}
}

class Contributor {
	var $name;
	var $email;
	var $contributions = array();
	
	function __construct($email, $name) {
		$this->email = $email;
		$this->name = $name;
	}
}

class Contribution {
	var $ref;
	var $link;
	var $author;
	var $size;
	var $comments;
	
	function __construct($ref, $link, $author, $size, $comments) {
		$this->ref = $ref;
		$this->link = $link;
		$this->author = $author;
		$this->size = $size;
		$this->comments = $comments;
	}
}

function contributors_sort_by_name($a, $b) {
	return strcasecmp($a->name, $b->name);
}

/**
 * The IPLogBugzillaBuilder queries Bugzilla to populate the log.
 * 
 * @internal
 */
class IPLogBugzillaBuilder {
    /* @var IPLog */
    var $iplog;
    var $project;
    var $corrections = array();
    
    static function assemble(&$iplog, &$project) {        
        $builder = new self($iplog, $project);
        $trace = trace("Assemble Bugzilla records for " . $project->getName());
        
        $builder->loadCorrections();
        $builder->assembleAttachmentContributions($trace);
        $builder->assembleCommentContributions($trace);
    }
    
    function __construct(&$iplog, &$project) {
        $this->iplog = $iplog;
        $this->project = $project;
        $this->committers = array();
        foreach(getCommittersForProject($project->getId()) as $committer)
            $this->committers[$committer->email] = $committer;
    }
       
    /**
     * We no longer support corrections, but there are a mess of them in the database already,
     * so we should honour what's there. At least for comments.
     * 
     * @internal
     */
    function loadCorrections() {
        global $App;
        
        $id = $this->project->getId();
        $sql = "SELECT ItemType as type, Action as action, ItemID as id FROM IPLogCorrections where ProjectId = '$id'";
        $result = $App->foundation_sql( $sql );
        while($row = mysql_fetch_assoc($result)) {
            $this->corrections[$row['type']][$row['action']][$row['id']] = 'remove';
        }
    }
    
    /**
     * Query the Bugzilla database for iplog+ flagged attachments in the project.
     * Assemble contributions from the results.
     * 
     * Skip attachments made by committers.
     * 
     * @internal
     * @param Tracer $trace
     */
    function assembleAttachmentContributions($trace) {
        global $App;
        
        $product = $this->project->getBugzillaProduct();
        $components = $this->project->getBugzillaComponents();
        if ($components) 
            $components = "'" . implode("','", $components) . "'";
        
        $sql = "
            SELECT
                bugs.bug_id as bug_id,
                bugs.short_desc as title,
                products.name as product,
                components.name as component,
                attachments.attach_id as attach_id,
                attachments.description as description,
                attachments.isobsolete as isobsolete,
                attachments.ispatch as ispatch,
                attachments.creation_ts as creation,
                LENGTH(attach_data.thedata) AS size,
                profiles.login_name as contributor,
                profiles.realname as realname
            FROM
                bugs
                join products on (bugs.product_id = products.id)
                join components on (bugs.component_id = components.id)
                join attachments on (bugs.bug_id = attachments.bug_id and attachments.isobsolete = 0)
                join attach_data on (attachments.attach_id = attach_data.id)
                join profiles on (attachments.submitter_id = profiles.userid)
                join flags on (attachments.attach_id = flags.attach_id and flags.status = '+')
                join flagtypes on (flags.type_id = flagtypes.id and flagtypes.name = 'iplog')
            WHERE
                products.name = '$product'
                and bugs.bug_id not in (select bg.bug_id from bug_group_map as bg join groups as g on (bg.group_id=g.id and g.name = 'Security_Advisories'))
                and bugs.bug_status IN ( 'RESOLVED', 'VERIFIED', 'CLOSED' )
                and bugs.resolution IN ( 'FIXED' )";
        if ($components)
            $sql .= " and bugs.component_id in (SELECT id FROM components WHERE product_id=products.id and name in ($components))";
        
        $trace->trace($sql);
        
        $result = $App->bugzilla_sql( $sql );
        
        while( $row = mysql_fetch_assoc($result) ) {
            $bugId = $row['bug_id'];
            $author = $row['contributor'];
            $creation = $row['creation'];
            $attachId = $row['attach_id'];
            
            // if (isset($this->corrections['CONTRIB']['RMA'][$attachId])) continue;
            
            $trace->trace("Reviewing attachment by $author bug $bugId attachment $attachId");
            
            if ($this->isCommitter($author, $creation)) continue;
            
            $name = $row['realname'];
            $ref = "$bugId#a$attachId";
            $size = ($attachId == 104976 ? 1543319 : $row['size']) . ' bytes';	                   
            $link = "https://bugs.eclipse.org/$bugId";
            $comment = $row['title'] . "\nAttachment $attachId: " . $row['description'];
            
            $trace->trace("Attachment contribution from $author bug $bugId attachment $attachId");
            $this->iplog->addContribution($author, $name, $ref, $bugId, $link, $size, $comment);
        }
    }
    
    /**
     * Query the Bugzilla database for iplog+ flagged bugs in the project.
     * Assemble contributions from the comments in those bugs.
     *
     * Skip comments made by committers.
     * Skip comments indicated in the corrections table (Foundation database).
     * 
     * @internal
     * @param Tracer $trace
     */
    function assembleCommentContributions($trace) {
        global $App;
    
        $product = $this->project->getBugzillaProduct();
        $components = $this->project->getBugzillaComponents();
        if ($components)
            $components = "'" . implode("','", $components) . "'";
    
        $sql = "
        		SELECT 
        			bugs.bug_id as bug_id, 
        			bugs.short_desc as title,
        			products.name as product,
        			components.name as component,
        			flagtypes.name as bugflag_name,
        			flags.status as bugflag_value,
                    longdescs.comment_id as comment_id,
                    longdescs.bug_when as creation,
                    LENGTH(longdescs.thetext) as size,
                    profiles.login_name as contributor,
                    profiles.realname as realname
        		FROM 
        			bugs 
    				join products on (bugs.product_id = products.id)
    				join components on (bugs.component_id = components.id)
    				join flags on (bugs.bug_id = flags.bug_id and flags.attach_id is null)
    				join flagtypes on (flags.type_id = flagtypes.id)
    				join longdescs on (bugs.bug_id = longdescs.bug_id)
                    join profiles on (profiles.userid = longdescs.who)
        		WHERE
        			products.name = '$product'
        			and flagtypes.name = 'iplog'
        			and flags.status = '+'
        			and bugs.bug_id not in (select bg.bug_id from bug_group_map as bg join groups as g on (bg.group_id=g.id and g.name = 'Security_Advisories'))
        			and bugs.bug_status IN ( 'RESOLVED', 'VERIFIED', 'CLOSED' )
        			and bugs.resolution IN ( 'FIXED' )";
        
        if ($components)
            $sql .= " and bugs.component_id in (SELECT id FROM components WHERE product_id=products.id and name in ($components))";
    
        $trace->trace($sql);

        $result = $App->bugzilla_sql( $sql );

        $bugs = array();

        while( $row = mysql_fetch_assoc($result) ) {
            $bugId = $row['bug_id'];
            $author = $row['contributor'];
            $creation = $row['creation'];
            $commentId = $row['comment_id'];
            
            $trace->trace("Reviewing comment by $author bug $bugId comment $commentId");

            if (isset($this->corrections['CONTRIB']['RMC'][$commentId])) continue;
            if ($this->isCommitter($author, $creation)) continue;

            $name = $row['realname'];
            $ref = "$bugId#c";
            $size = $row['size'] . ' bytes';
            $link = "https://bugs.eclipse.org/$bugId";
            $comment = $row['title'] . "\n" . 'Comment';

            $trace->trace("Comment contribution from $author bug $bugId comment $commentId");
            $this->iplog->addContribution($author, $name, $ref, $bugId, $link, $size, $comment);
        }
    }
    
    /**
     * Answers true if the author was/is a committer on the given date.
     * 
     * @internal
     * @param string $author email address
     * @param string $when date in a strtotime-parseable format
     * @return boolean
     */
    private function isCommitter($author, $when) {
        if (!isset($this->committers[$author])) return false;
        return $this->committers[$author]->isCommitter($this->project->getId(), $when);
    }
}
?>