/*
 * Copyright (C) 2003 EBI, GRL
 * 
 * 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 org.ensembl.healthcheck.testcase.generic;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.ensembl.healthcheck.DatabaseRegistryEntry;
import org.ensembl.healthcheck.ReportManager;
import org.ensembl.healthcheck.testcase.SingleDatabaseTestCase;

/**
 * Compare the biotypes in the current database with those from the equivalent
 * database on the secondary server.
 */

public class ComparePreviousVersionBiotypes extends SingleDatabaseTestCase {

	private static final double THRESHOLD = 0.78; // if old/new biotypes less than
																								// this, fail

	/**
	 * Create a new XrefTypes testcase.
	 */
	public ComparePreviousVersionBiotypes() {

		addToGroup("post_genebuild");
		addToGroup("release");
		setDescription("Compare the biotypes in the current database with those from the equivalent database on the secondary server");

	}

	/**
	 * Run the test.
	 * 
	 * @param dbre
	 *          The database to use.
	 * @return true if the test pased.
	 * 
	 */
	public boolean run(DatabaseRegistryEntry dbre) {

		boolean result = true;

		DatabaseRegistryEntry sec = getEquivalentFromSecondaryServer(dbre);

		if (sec == null) {
			logger.warning("Can't get equivalent database for " + dbre.getName());
			return true;
		}

		logger.finest("Equivalent database on secondary server is " + sec.getName());

		Map currentCounts = getCounts(dbre);
		Map secondaryCounts = getCounts(sec);

		// compare each of the secondary (previous release, probably) with current
		Set externalDBs = secondaryCounts.keySet();
		Iterator it = externalDBs.iterator();
		while (it.hasNext()) {

			String biotype = (String) it.next();

			int secondaryCount = ((Integer) (secondaryCounts.get(biotype))).intValue();

			// check it exists at all
			if (currentCounts.containsKey(biotype)) {

				int currentCount = ((Integer) (currentCounts.get(biotype))).intValue();

				if (((double) currentCount / (double) secondaryCount) < THRESHOLD) {
					ReportManager.problem(this, dbre.getConnection(), sec.getName() + " contains " + secondaryCount + " bioytypes of type "
							+ biotype + " but " + dbre.getName() + " only has " + currentCount);
					result = false;
				} else {

					ReportManager.correct(this, dbre.getConnection(), sec.getName() + " contains " + secondaryCount + " biotypes of type "
							+ biotype + " and " + dbre.getName() + " has " + currentCount + " - greater or within tolerance");

				}

			} else {
				ReportManager.problem(this, dbre.getConnection(), sec.getName() + " contains " + secondaryCount + " xrefs of type "
						+ biotype + " but " + dbre.getName() + " has none");
				result = false;
			}
		}
		return result;

	} // run

	// ----------------------------------------------------------------------

	private Map getCounts(DatabaseRegistryEntry dbre) {

		Map result = new HashMap();

		try {

			Statement stmt = dbre.getConnection().createStatement();

			logger.finest("Getting biotype counts for " + dbre.getName());

			ResultSet rs = stmt.executeQuery("SELECT DISTINCT(biotype),COUNT(*) AS count FROM gene GROUP BY biotype;");

			while (rs != null && rs.next()) {
				result.put(rs.getString("biotype"), new Integer(rs.getInt("count")));
				logger.finest(rs.getString("biotype") + " " + rs.getInt("count"));
			}

			stmt.close();

		} catch (SQLException e) {
			e.printStackTrace();
		}

		return result;
	}

	// ------------------------------------------------------------------------

} // ComparePreviousVersionBiotypes

Check biotype counts in new database vs old database and warn if there are significantly less.