/*
 *****************************************************************************
 * Copyright (C) 2000-2004, International Business Machines Corporation and  *
 * others. All Rights Reserved.                                              *
 *****************************************************************************
 */
package com.ibm.rbm;


import java.io.*;
import java.util.*;

import org.apache.xerces.parsers.DOMParser;
import org.w3c.dom.*;
import org.xml.sax.*;

/**
 * RBReporterScaner is a utility class for RBReporter. It creates a report from an xml settings
 * file that scans code for resources and compares them against a resource bundle.
 * 
 * @author Jared Jackson
 * @see com.ibm.rbm.RBReporter
 */
public class RBReporterScanner {
	private Bundle       bundle;
	private Document     config;
	private Hashtable    fileRules;
	private Hashtable    parseRules;
	private Hashtable    results;
	private Hashtable    missing;
	private boolean      resultsFound;
	
	protected RBReporterScanner(Bundle bundle, File configFile) throws IOException {
		resultsFound = false;
		this.bundle = bundle;
		
		try {
			InputSource is = new InputSource(new FileInputStream(configFile));
			DOMParser parser = new DOMParser();
			parser.parse(is);
			config = parser.getDocument();
		} catch (SAXException saxe) {
			throw new IOException("Illegal XML Document: " + saxe.getMessage());
		}
		
		Element root = config.getDocumentElement();
		fileRules = getFileRules(root);
		parseRules = getParseRules(root);
		
		results = new Hashtable();
		Enumeration enum = bundle.allItems.keys();
		while (enum.hasMoreElements()) {
			String key = (String)enum.nextElement();
			BundleItem item = (BundleItem)bundle.allItems.get(key);
			results.put(key, new ScanResult(item));
		}
		
		missing = new Hashtable();
	}
	
	protected int getNumberResourcesFound() {
		return results.size();
	}
	
	protected int getNumberMissingResources() {
		return missing.size();
	}
	
	protected int getNumberUnusedResources() {
		int count = 0;
		Enumeration enum = results.elements();
		while (enum.hasMoreElements()) {
			ScanResult result = (ScanResult)enum.nextElement();
			if (result.getOccurances().size() < 1) count++;
		}
		return count;
	}
	
	protected Vector getMissingResources() {
		Enumeration enum = missing.elements();
		Vector v = new Vector();
		while (enum.hasMoreElements()) v.addElement(enum.nextElement());
		return v;
	}
	
	protected Vector getUnusedResources() {
		Enumeration enum = results.elements();
		Vector v = new Vector();
		while (enum.hasMoreElements()) {
			ScanResult result = (ScanResult)enum.nextElement();
			if (result.getOccurances().size() < 1) {
				v.addElement(result);
			}
		}
		return v;
	}
	
	protected boolean performScan() throws IOException {
		resultsFound = false;
		
		Element root = config.getDocumentElement();
		NodeList nl = root.getElementsByTagName("Scan");
		if (nl.getLength() < 1) return resultsFound;
		Element scan_elem = (Element)nl.item(0);
		nl = scan_elem.getElementsByTagName("Directory");
		for (int i=0; i < nl.getLength(); i++) {
			Element dir_elem = (Element)nl.item(i);
			File directory = new File(dir_elem.getAttribute("location"));
			boolean recurse = dir_elem.getAttribute("recurse_directories").equalsIgnoreCase("true");
			NodeList rules_list = dir_elem.getElementsByTagName("Rules");
			if (rules_list.getLength() < 1) continue;
			Element rules_elem = (Element)rules_list.item(0);
			NodeList frules_list = rules_elem.getElementsByTagName("ApplyFileRule");
			// For each file rule
			for (int j=0; j < frules_list.getLength(); j++) {
				Element frule_elem = (Element)frules_list.item(j);
				FileRule frule = (FileRule)fileRules.get(frule_elem.getAttribute("name"));
				if (frule == null) continue;
				NodeList prules_list = frule_elem.getElementsByTagName("ApplyParseRule");
				Vector prules_v = new Vector();
				// For each parse rule
				for (int k=0; k < prules_list.getLength(); k++) {
					Element prule_elem = (Element)prules_list.item(k);
					ParseRule prule = (ParseRule)parseRules.get(prule_elem.getAttribute("name"));
					if (prule == null) continue;
					prules_v.addElement(prule);
				}
				if (prules_v.size() < 1) continue;
				scanDirectory(directory, frule, prules_v, recurse);
			}
		}
		
		return resultsFound;
	}
	
	private void scanDirectory(File directory, FileRule frule, Vector prules, boolean recurse) throws IOException {
		
		// Recursion step
		if (recurse) {
			File children[] = directory.listFiles(new java.io.FileFilter(){
				public boolean accept(File f) {
					return f.isDirectory();
				}
				
				public String getDescription() {
					return "";
				}
			});
			for (int i=0; i < children.length; i++) {
				File new_directory = children[i];
				scanDirectory(new_directory, frule, prules, recurse);
			}
		}
		// Go through each acceptable file
		File children[] = directory.listFiles();
		for (int i=0; i < children.length; i++) {
			File f = children[i];
			if (f.isDirectory() || !(frule.applyRule(f.getName()))) continue;
			FileReader fr = new FileReader(f);
			BufferedReader br = new BufferedReader(fr);
			String line = null;
			int line_count = 0;
			// Read the file line by line
			while ((line = br.readLine()) != null) {
				line_count++;
				Vector findings = new Vector();
				// Apply all parse rules to each line
				for (int j=0; j < prules.size(); j++) {
					ParseRule prule = (ParseRule)prules.elementAt(j);
					Vector temp_results = prule.applyRule(line);
					for (int k=0; k < temp_results.size(); k++) {
						findings.addElement(temp_results.elementAt(k));
					}
				}
				for (int j=0; j < findings.size(); j++) {
					String name = (String)findings.elementAt(j);
					Occurance occ = new Occurance(f.getName(), f.getAbsolutePath(), line_count);
					// If the name is found in the resource bundles derived hashtable
					if (results.containsKey(name)) {
						ScanResult scan_res = (ScanResult)results.get(name);
						scan_res.addOccurance(occ);
					} else {
						// Add it to the missing results
						ScanResult scan_res = new ScanResult(new BundleItem(null, name, "*unknown*"));
						scan_res.addOccurance(occ);
						missing.put(name, scan_res);
						results.put(name, scan_res);
					}
				}
			}
		}
	}
	
	private Hashtable getFileRules(Element root) {
		Hashtable result = new Hashtable();
		NodeList frules_list = root.getElementsByTagName("FileRules");
		Element frules_elem = null;
		if (frules_list.getLength() > 0) frules_elem = (Element)frules_list.item(0);
		if (frules_elem == null) return result;
		frules_list = frules_elem.getElementsByTagName("FileRule");
		for (int i=0; i < frules_list.getLength(); i++) {
			Element elem = (Element)frules_list.item(i);
			FileRule frule = new FileRule(elem.getAttribute("name"), elem.getAttribute("starts_with"),
										  elem.getAttribute("ends_with"), elem.getAttribute("contains"));
			result.put(elem.getAttribute("name"), frule);
		}
		return result;
	}
	
	private Hashtable getParseRules(Element root) {
		Hashtable result = new Hashtable();
		NodeList prules_list = root.getElementsByTagName("ParseRules");
		Element prules_elem = null;
		if (prules_list.getLength() > 0)
			prules_elem = (Element)prules_list.item(0);
		if (prules_elem == null)
			return result;
		prules_list = prules_elem.getElementsByTagName("ParseRule");
		for (int i=0; i < prules_list.getLength(); i++) {
			Element elem = (Element)prules_list.item(i);
			ParseRule prule = new ParseRule(elem.getAttribute("name"), elem.getAttribute("follows"),
											elem.getAttribute("precedes"));
			result.put(elem.getAttribute("name"), prule);
		}
		return result;
	}
}

class FileRule {
	String name;
	String starts_with;
	String ends_with;
	String contains;
	
	FileRule(String name, String starts_with, String ends_with, String contains) {
		this.name = name;
		this.starts_with = starts_with;
		this.ends_with = ends_with;
		this.contains = contains;
	}
	
	boolean applyRule(String source) {
		boolean accept = true;
		if (starts_with != null && starts_with.length() > 0 && !(source.startsWith(starts_with))) accept = false;
		if (ends_with != null && ends_with.length() > 0 && !(source.endsWith(ends_with))) accept = false;
		if (contains != null && contains.length() > 0 && source.indexOf(contains) < 0) accept = false;
		return accept;
	}
}

class ParseRule {
	String name;
	String before;
	String after;
	
	ParseRule(String name, String before, String after) {
		this.name = name;
		this.before = before;
		this.after = after;
	}
	
	// returns the vector of strings found after before and before after
	
	Vector applyRule(String source) {
		Vector v = new Vector();
		if (before != null && before.length() > 0) {
			if (after != null && after.length() > 0) {
				// Both before and after non-empty
				int before_index = -1;
				int after_index = -1;
				while ((before_index = source.indexOf(before, ++before_index)) >= 0) {
					//before_index = source.indexOf(before, before_index);
					after_index = -1;
					after_index = source.indexOf(after, before_index + before.length()+1);
					if (after_index < 0 || before_index < 0 || before.length() < 0) {
					    break;
					}
					v.addElement(source.substring(before_index + before.length(), after_index));
					before_index = after_index;
				}
			} else {
				// Before non-empty, after empty
				int index = -1;
				while (source.indexOf(before, ++index) >= 0) {
					index = source.indexOf(before, index);
					String result = source.substring(index + before.length(), source.length());
					if (result != null && result.length() > 0) v.addElement(result);
				}
			}
		} else if (after != null && after.length() > 0) {
			// Before empty, after not
			int index = -1;
			while (source.indexOf(after, ++index) >= 0) {
				index = source.indexOf(before, index);
				String result = source.substring(0, index);
				if (result != null && result.length() > 0) v.addElement(result);
			}
		} else {
			// Before and after empty
			v.addElement(source);
		}
		return v;
	}
}