package lib;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * SQL helper to interact with the database
 * 
 * @author Manuel
 */
public class SQLConnection {
	
	Connection con;

	public SQLConnection() {
		this("102-012/sven");
	}
	
	public SQLConnection(String url) {
		this(url, "intabi19", "hallo");
	}
	
	public SQLConnection(String url, String username, String password) {
		try {
			this.con = DriverManager.getConnection("jdbc:mysql://" + url, username, password);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Executes a query without storing the return values
	 * 
	 * @param sqlQuery SQL command to be executed
	 */
	public void execute(String sqlQuery) {
		try {
			//System.out.println("SQL: " + sqlQuery);
			this.con.createStatement().execute(sqlQuery);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * @returns table headers in a list from an existing meta data object
	 */
	private ArrayList<String> getColumnNames(ResultSetMetaData metaData) throws SQLException {
		int columns = metaData.getColumnCount();
		
		ArrayList<String> columnTitles = new ArrayList<>();
		for (int i = 0; i < columns; i++) {
			columnTitles.add(metaData.getColumnLabel(i + 1));
		}
		
		return columnTitles;
	}

	/**
	 * Converts the database return values into a usable format
	 * 
	 * @param sqlQuery SQL command to be executed
	 * @return a list of rows that are keyed by their column name
	 */
	public ArrayList<HashMap<String, String>> queryToMap(String sqlQuery) {
		ArrayList<HashMap<String, String>> data = new ArrayList<>();
		
		//System.out.println("SQLq: " + sqlQuery);
		
		try {
			ResultSet result = this.con.createStatement().executeQuery(sqlQuery);
			ResultSetMetaData metaData = result.getMetaData();
			
			int columns = metaData.getColumnCount();
			
			ArrayList<String> columnTitles = getColumnNames(metaData);
			
			// iterate over all rows
			while (result.next()) {
				HashMap<String, String> row = new HashMap<>();
				for (int i = 0; i < columns; i++) {
					// copy items from table to row
					row.put(columnTitles.get(i), result.getString(i + 1));
				}
				data.add(row);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return data;
	}
	
	@Deprecated
	public ArrayList<ArrayList<String>> queryToArray(String sqlQuery) {
		ArrayList<ArrayList<String>> data = new ArrayList<>();
		
		try {
			ResultSet result = this.con.createStatement().executeQuery(sqlQuery);
			ResultSetMetaData metaData = result.getMetaData();
			
			int columns = metaData.getColumnCount();
			
			// iterate over all rows
			while (result.next()) {
				ArrayList<String> row = new ArrayList<>();
				for (int i = 0; i < columns; i++) {
					// copy items from table to row
					row.add(result.getString(i + 1));
				}
				data.add(row);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return data;
	}
	
	/**
	 * Closes the connection with the database
	 */
	public void close() {
		try {
			this.con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}
