/*******************************************************************************
 * Copyright (c) 2009, 2011 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.jpa.db.internal.driver;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.eclipse.jpt.common.utility.internal.StringTools;
import org.eclipse.jpt.common.utility.internal.Tools;
import org.eclipse.jpt.jpa.db.Database;
import org.eclipse.jpt.jpa.db.DatabaseObject;
import org.eclipse.jpt.jpa.db.Schema;
import org.eclipse.jpt.jpa.db.Table;

/**
 * MySQL is a bit unusual in that it does <em>not</em> fold <em>regular</em>
 * identifiers and most of its identifiers are <em>not</em> case-sensitive
 * (except in special cases, described below). Even <em>delimited</em> identifiers
 * are case-<em>in</em>sensitive. (Delimiters are only needed for identifiers
 * that contain special characters or are reserved words.)
 * <p>
 * MySQL handles the case-sensitivity of databases and tables according to the
 * value of the system variable <code>lower_case_table_names</code>:<ul>
 * <li>0 (Unix/Linux default): database and table names are <em>not</em> folded
 * and they are case-sensitive
 * <li>1 (Windows default): database and table names are folded to lowercase
 * and they are <em>not</em> case-sensitive
 * <li>2 (Mac OS X default): database and table names are <em>not</em> folded
 * and they are <em>not</em> case-sensitive
 * </ul>
 * These values will not work perfectly on all platforms because databases are
 * stored as directories and tables are stored as files in the underlying
 * O/S; and the actual case-sensitivity of the names will ulimately be
 * determined by the behavior of filenames on the O/S.
 * <p>
 * See http://dev.mysql.com/doc/refman/5.0/en/identifier-case-sensitivity.html.
 */
class MySQL
	extends AbstractDTPDriverAdapter
{
	/** lazy-initialized */
	private int lower_case_table_names = -1;

	MySQL(Database database) {
		super(database);
	}

	/**
	 * The DTP model for MySQL has a database that contains no catalogs;
	 * but, instead, directly holds a single schema with the same name as
	 * the database. (This is hard-coded in
	 * {@link org.eclipse.datatools.enablement.mysql.catalog.MySqlCatalogDatabase#getSchemas()}.)
	 * Although you can qualify identifiers with a database name
	 * in MySQL, only the database specified at login seems to be available
	 * in the DTP model....
	 * <p>
	 * <strong>NB:</strong> In MySQL DDL, <code>SCHEMA</code> is a synonym
	 * for <code>DATABASE</code>; but the JDBC
	 * method {@link java.sql.DatabaseMetaData#getSchemas()} returns an empty list,
	 * while {@link java.sql.DatabaseMetaData#getCatalogs()} returns a list of the
	 * available databases.
	 * You can also use the JDBC method {@link java.sql.Connection#setCatalog(String)}
	 * to set the default database.
	 */
	@Override
	CatalogStrategy buildCatalogStrategy() {
		return new NoCatalogStrategy(this.database.getDTPDatabase());
	}

	/**
	 * There are some cases where MySQL folds identifiers, but using the
	 * non-folding strategy should work:<ul>
	 * <li>We only fold identifiers when
	 * converting them to names; but MySQL is case-<em>in</em>sensitive
	 * when it is folding database and table names
	 * (<code>lower_case_table_names</code>=1), so lookups will work
	 * fine without any folding anyways.
	 * <li>We only test whether a name is already folded when determining
	 * whether it must be delimited; and MySQL ignores delimiters
	 * when it comes to case-sensitivity, so we can leave any "normal"
	 * mixed-case names undelimited. (MySQL only requires delimiters for
	 * special characters and reserved words.)
	 * </ul>
	 */
	@Override
	FoldingStrategy buildFoldingStrategy() {
		return NonFoldingStrategy.instance();
	}

	@Override
	void addDefaultSchemaNamesTo(ArrayList<String> names) {
		names.add(this.database.getName());
	}


	// ********** identifiers/names **********

	/**
	 * MySQL is the only vendor that allows a digit.
	 * Although, the name cannnot be <em>all</em> digits
	 * (unless delimited).
	 */
	@Override
	boolean characterIsRegularNameStart(char c) {
		return Character.isDigit(c) || super.characterIsRegularNameStart(c);
	}

	@Override
	char[] getExtendedRegularNameStartCharacters() {
		return EXTENDED_REGULAR_NAME_START_CHARACTERS;
	}
	private static final char[] EXTENDED_REGULAR_NAME_START_CHARACTERS = new char[] { '_', '$' };

	@Override
	String delimitName(String name) {
		return StringTools.delimit(name, BACKTICK);
	}

	/**
	 * By default, MySQL delimits identifiers with backticks (<code>`</code>);
	 * but it can also be configured to use double-quotes.
	 */
	//TODO query for ANSI_QUOTES setting
	@Override
	boolean identifierIsDelimited(String identifier) {
		return StringTools.stringIsDelimited(identifier, BACKTICK)
					|| super.identifierIsDelimited(identifier);
	}
	private static final char BACKTICK = '`';

	/**
	 * This method should only affect whether entity
	 * generation will generate a specified table or column identifier when the
	 * default identifier is not a match. Worst case: Entity generation will
	 * generate explicit identifiers unnecessarily for columns when tables are
	 * case-sensitive. The generated annotation will be valid but the column
	 * name will be redundant.
	 */
	@Override
	boolean regularNamesMatch(String name1, String name2) {
		return this.tableNamesAreCaseSensitive() ?
				name1.equals(name2) :
				name1.equalsIgnoreCase(name2);
	}


	// ********** selecting database objects **********

	/**
	 * DTP schemata are MySQL databases(?). Of course, we only have one per
	 * connection....
	 */
	@Override
	public Schema selectSchemaForIdentifier(Iterable<Schema> schemata, String identifier) {
		return this.tableNamesAreCaseSensitive() ?
				this.selectDatabaseObjectForIdentifierRespectCase(schemata, identifier) :
				super.selectSchemaForIdentifier(schemata, identifier);
	}

	@Override
	public Table selectTableForIdentifier(Iterable<Table> tables, String identifier) {
		return this.tableNamesAreCaseSensitive() ?
				this.selectDatabaseObjectForIdentifierRespectCase(tables, identifier) :
				super.selectTableForIdentifier(tables, identifier);
	}

	<T extends DatabaseObject> T selectDatabaseObjectForIdentifierRespectCase(Iterable<T> databaseObjects, String identifier) {
		return this.selectDatabaseObjectNamedRespectCase(databaseObjects, this.convertIdentifierToName(identifier));
	}

	/**
	 * MySQL database object names are usually case-insensitive;
	 * the exception being databases (schemata) and tables when the system
	 * variable <code>lower_case_table_names</code> is 0 (the default on
	 * UNIX/Linux). (For some odd reason, trigger names are also
	 * case-sensitive.... Fortunately, we don't care yet.)
	 */
	@Override
	<T extends DatabaseObject> T selectDatabaseObjectNamed(Iterable<T> databaseObjects, String name) {
		return this.selectDatabaseObjectNamedIgnoreCase(databaseObjects, name);
	}


	// ********** misc **********

	private boolean tableNamesAreCaseSensitive() {
		return this.getLowerCaseTableNamesValue() == 0;
	}

	private int getLowerCaseTableNamesValue() {
		if (this.lower_case_table_names == -1) {
			this.lower_case_table_names = this.buildLowerCaseTableNamesValue();
		}
		return this.lower_case_table_names;
	}

	/**
	 * If we don't have a live connection (i.e. we are working off-line),
	 * use the current O/S default setting(?).
	 */
	private int buildLowerCaseTableNamesValue() {
		int dbValue = this.getLowerCaseTableNamesValueFromDatabase();
		return (dbValue != -1) ? dbValue : this.getLowerCaseTableNamesValueFromOS();
	}

	private int getLowerCaseTableNamesValueFromDatabase() {
		if (this.getConnectionProfile().isDisconnected()) {
			return -1;
		}
		// the underscore is a wild character on MySQL, so we need to escape it
		List<Map<String, Object>> rows = this.execute("show variables like 'lower\\_case\\_table\\_names'"); //$NON-NLS-1$
		if (rows.isEmpty()) {
			return -1;
		}
		Map<String, Object> row = rows.get(0);
		if (Tools.valuesAreEqual(row.get("Variable_name"), "lower_case_table_names")) { //$NON-NLS-1$ //$NON-NLS-2$
			return Integer.valueOf((String) row.get("Value")).intValue(); //$NON-NLS-1$
		}
		return -1;
	}

	/**
	 * Make a best guess at what the setting might be:
	 * Return the default value for the current O/S (unfortunately this is the
	 * client O/S, not the MySQL Server O/S...).
	 */
	private int getLowerCaseTableNamesValueFromOS() {
		if (Tools.osIsMac()) {
			return 2;
		}
		if (Tools.osIsWindows()) {
			return 1;
		}
		return 0;  // Linux etc.
	}


	// ********** factory **********

	static class Factory implements DTPDriverAdapterFactory {
		private static final String[] VENDORS = {
				"MySql" //$NON-NLS-1$
			};
		public String[] getSupportedVendors() {
			return VENDORS;
		}
		public DTPDriverAdapter buildAdapter(Database database) {
			return new MySQL(database);
		}
	}
}
