/*
 * This file is part of the DistSim distributed simulation framework (client)
 * Copyright (C) 2007 Ulf Hermann
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * 
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package brn.distsim.client.data;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.LinkedList;
import java.util.List;
import java.util.Vector;

public class Results {

	private Statement statement;

	private int simulationId;

	public Results(Connection results, int id) throws SQLException {
		statement = results.createStatement();
		simulationId = id;
	}

	public void deleteAll() throws SQLException {
		statement
				.executeUpdate("DELETE FROM java_lang_Object WHERE simulationId="
						+ simulationId + ";");
		statement.executeUpdate("DELETE FROM out_files WHERE simulationId="
				+ simulationId + ";");
		statement.executeUpdate("DELETE FROM progress WHERE simulationId="
				+ simulationId + ";");
		statement
				.executeUpdate("DELETE FROM class_hierarchy WHERE simualtionId="
						+ simulationId + ";");
		statement.executeUpdate("DELETE FROM class_members WHERE simualtionId="
				+ simulationId + ";");
		// TODO: delete from other tables, announced in extra_tables
	}

	public List<String> getTableNames() throws SQLException {
		ResultSet names = statement
				.executeQuery("SELECT subclass FROM class_hierarchy WHERE simulationId="
						+ simulationId + ";");
		List<String> nameList = new LinkedList<String>();
		while (names.next()) {
			nameList.add(names.getString(1));
		}
		return nameList;
	}

	public Vector<String> getColumnNames(String name) throws SQLException {
		Vector<String> result = new Vector<String>();
		ResultSet fields = statement.executeQuery("SHOW COLUMNS FROM " + name
				+ ";");
		while (fields.next()) {
			result.add(fields.getString(1));
		}
		return result;
	}

	public Vector<Vector<String>> getData(String name) throws SQLException {
		ResultSet data = statement
				.executeQuery("SELECT SQL_CALC_FOUND_ROWS * FROM "
						+ name
						+ " WHERE primary_key IN (SELECT primary_key FROM java_lang_Object WHERE simulationId="
						+ simulationId + ") ORDER BY primary_key;");
		data.last();
		Vector<Vector<String>> result = new Vector<Vector<String>>(data
				.getRow());
		int numCols = data.getMetaData().getColumnCount();
		data.beforeFirst();
		while (data.next()) {
			Vector<String> row = new Vector<String>(numCols);
			for (int i = 1; i <= numCols; ++i) {
				row.add(data.getString(i));
			}
			result.add(row);
		}
		return result;
	}

	public String getSuperclass(String name) throws SQLException {
		ResultSet superName = statement
				.executeQuery("SELECT superclass FROM class_hierarchy WHERE simulationId="
						+ simulationId + " AND subclass='" + name + "';");
		if (superName.next()) {
			String ret = superName.getString(1);
			return ret;
		} else
			return null;
	}

	public Vector<String> getSubTableColumnNames(String subName)
			throws SQLException {
		Vector<String> result = new Vector<String>();
		ResultSet fields = statement.executeQuery("SHOW COLUMNS FROM "
				+ subName + ";");
		fields.next(); // discard "primary_key"
		while (fields.next()) {
			result.add(fields.getString(1));
		}
		return result;
	}

	public Vector<Vector<String>> getSuperClassData(String subName, String name)
			throws SQLException {
		ResultSet data = statement
				.executeQuery("SELECT SQL_CALC_FOUND_ROWS * FROM "
						+ subName
						+ " WHERE primary_key IN (SELECT primary_key FROM "
						+ name
						+ " WHERE primary_key IN (SELECT primary_key FROM java_lang_Object WHERE simulationId="
						+ simulationId + ")) ORDER BY primary_key;");
		data.last();
		Vector<Vector<String>> result = new Vector<Vector<String>>(data
				.getRow());
		int numCols = data.getMetaData().getColumnCount();
		data.beforeFirst();
		while (data.next()) {
			Vector<String> row = new Vector<String>(numCols - 1);
			for (int i = 2; i <= numCols; ++i) {
				row.add(data.getString(i));
			}
			result.add(row);
		}
		return result;
	}

	public List<String> getChildTableNames(String parentTable)
			throws SQLException {
		ResultSet names = statement
				.executeQuery("SELECT member FROM class_members WHERE simulationId="
						+ simulationId + " AND class='" + parentTable + "';");
		List<String> nameList = new LinkedList<String>();
		while (names.next()) {
			nameList.add(names.getString(1));
		}
		return nameList;
	}

	public Vector<Vector<String>> getChildData(String table, int parentKey) throws SQLException {
		ResultSet data = statement
				.executeQuery("SELECT * FROM "
						+ table
						+ " WHERE uid=" + parentKey + ";");
		data.last();
		Vector<Vector<String>> result = new Vector<Vector<String>>(data
				.getRow());
		int numCols = data.getMetaData().getColumnCount();
		data.beforeFirst();
		while (data.next()) {
			Vector<String> row = new Vector<String>(numCols - 1);
			for (int i = 2; i <= numCols; ++i) {
				row.add(data.getString(i));
			}
			result.add(row);
		}
		return result;
	}

}
