/*
 * FindBugs - Find Bugs in Java programs
 * Copyright (C) 2003-2008 University of Maryland
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package edu.umd.cs.findbugs;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.util.HashMap;

import edu.umd.cs.findbugs.ba.AnalysisContext;
import edu.umd.cs.findbugs.util.Util;

/**
 * @author pwilliam
 */
public class BugRanker {
	
	public BugRanker(URL u) throws UnsupportedEncodingException, IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(u.openStream(), "UTF-8"));
		while (true) {
			String s = in.readLine();
			if (s == null) break;
			String parts [] = s.split(" ");
			int rank = Integer.parseInt(parts[0]);
			String kind = parts[1];
			String what = parts[2];
			if (kind.equals("BugPattern"))
				bugPatterns.put(what, rank);
			else if (kind.equals("BugKind"))
				bugKinds.put(what, rank);
			else if (kind.equals("Category"))
				bugCategories.put(what, rank);
			else
				AnalysisContext.logError("Can't parse bug rank " + s);
		}
		Util.closeSilently(in);
	}

	HashMap<String, Integer> bugPatterns = new HashMap<String, Integer>();

	HashMap<String, Integer> bugKinds = new HashMap<String, Integer>();

	HashMap<String, Integer> bugCategories = new HashMap<String, Integer>();

	public int rankBug(BugInstance bug) {
		BugPattern bugPattern = bug.getBugPattern();
		int priority = bug.getPriority();
		return rankBugPattern(bugPattern, priority);

	}

	/**
     * @param bugPattern
     * @param priority
     * @return
     */
    public int rankBugPattern(BugPattern bugPattern, int priority) {
	    Integer value = rankBugPattern(bugPattern);
		if (value == null)
			return 25;
		int v = value.intValue();
		switch (priority) {
		case Priorities.HIGH_PRIORITY:
			break;
		case Priorities.NORMAL_PRIORITY:
			v += 2;
			break;
		case Priorities.LOW_PRIORITY:
			v += 5;
			break;
		default:
			return 26;
		}
		return Math.min(20, Math.max(1, v));
    }

	private Integer rankBugPattern(BugPattern bugPattern) {
	    String type = bugPattern.getType();
		Integer value = bugPatterns.get(type);
		if (value == null) {
			value = bugKinds.get(bugPattern.getAbbrev());
			if (value == null)
				value = bugCategories.get(bugPattern.getCategory());
			bugPatterns.put(type, value);
		}
	    return value;
    }
	
	public static int findRank(BugInstance bug) {
		for(Plugin p : DetectorFactoryCollection.instance().plugins()) {
			BugRanker r = p.getBugRanker();
			int rank = r.rankBug(bug);
			if (rank <= 20) 
				return rank;
		}
		return 30;
	}

	public static int findRank(BugPattern pattern, int priority) {
		for(Plugin p : DetectorFactoryCollection.instance().plugins()) {
			BugRanker r = p.getBugRanker();
			int rank = r.rankBugPattern(pattern, priority);
			if (rank <= 20) 
				return rank;
		}
		return 30;
	}


}

@@ -3160,24 +3160,46 @@
 ance bug) %7B%0A
+%09%09int finalRank = 30;%0A
 %09%09for(Plugin
@@ -3287,35 +3287,55 @@
 anker();%0A%09%09%09
+f
 in
-t r
+alR
 ank = 
+Math.min(finalRank,
 r.rankBug(bu
@@ -3340,32 +3340,16 @@
 bug)
+)
 ;%0A
-%09%09%09if (rank %3C= 20) 
 %0A%09%09
+%7D%0A
 %09%09re
@@ -3353,37 +3353,25 @@
 %09return 
-rank;%0A%09%09%7D%0A%09%09return 30
+finalRank
 ;%0A%09%7D%0A%0A%09p
@@ -3432,16 +3432,38 @@
 rity) %7B%0A
+%09%09int finalRank = 30;%0A
 %09%09for(Pl
@@ -3559,26 +3559,47 @@
 r();%0A%09%09%09
+f
 in
-t r
+alR
 ank =
+ Math.min(finalRank,
  r.rankB
@@ -3630,62 +3630,33 @@
 ity)
+)
 ;%0A%09%09
-%09if (rank %3C= 20) %0A%09%09%09%09return rank;%0A%09%09%7D%0A%09%09return 30
+%7D%0A%09%09return finalRank
 ;%0A%09%7D

Fix ranker; use minimum from all plugins