package mil.nga.geopackage;

import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

import com.j256.ormlite.jdbc.JdbcConnectionSource;
import com.j256.ormlite.logger.Level;
import com.j256.ormlite.logger.LocalLogBackend;
import com.j256.ormlite.logger.LogBackendType;
import com.j256.ormlite.logger.LoggerFactory;
import com.j256.ormlite.support.ConnectionSource;

import mil.nga.geopackage.db.GeoPackageConnection;
import mil.nga.geopackage.db.GeoPackageTableCreator;
import mil.nga.geopackage.io.GeoPackageIOUtils;
import mil.nga.geopackage.validate.GeoPackageValidate;

/**
 * GeoPackage Manager used to create and open GeoPackages
 * 
 * @author osbornb
 */
public class GeoPackageManager {

	static {
		// Change the ORMLite log backend
		System.setProperty(LocalLogBackend.LOCAL_LOG_LEVEL_PROPERTY,
				Level.ERROR.name());
		LoggerFactory.setLogBackendType(LogBackendType.JAVA_UTIL);
	}

	/**
	 * Create a GeoPackage
	 * 
	 * @param file
	 *            file
	 * @return created file
	 * @since 4.0.0
	 */
	public static File create(File file) {
		return create(file, true);
	}

	/**
	 * Create a GeoPackage
	 * 
	 * @param file
	 *            file
	 * @param validate
	 *            validate the file extension
	 * @return created file
	 * @since 4.0.0
	 */
	public static File create(File file, boolean validate) {

		boolean isGeoPackage = true;

		// Validate or add the file extension
		if (GeoPackageIOUtils.hasFileExtension(file)) {
			if (validate) {
				GeoPackageValidate.validateGeoPackageExtension(file);
			} else {
				isGeoPackage = GeoPackageValidate.hasGeoPackageExtension(file);
			}
		} else {
			file = addExtension(file);
		}

		if (file.exists()) {
			throw new GeoPackageException(
					"File already exists: " + file.getAbsolutePath());
		}

		// Create the file connection
		GeoPackageConnection connection = connect(file);

		try {

			// Set GeoPackage values and create required tables
			if (isGeoPackage) {

				// Set the GeoPackage application id and user version
				connection.setApplicationId();
				connection.setUserVersion();

				// Create the minimum required tables
				GeoPackageTableCreator tableCreator = new GeoPackageTableCreator(
						connection);
				tableCreator.createRequired();

			}

		} finally {
			connection.close();
		}

		return file;
	}

	/**
	 * Open a GeoPackage
	 * 
	 * @param file
	 *            file
	 * @return GeoPackage
	 */
	public static GeoPackage open(File file) {
		return open(file, true);
	}

	/**
	 * Open a GeoPackage
	 * 
	 * @param file
	 *            file
	 * @param validate
	 *            validate the GeoPackage
	 * @return GeoPackage
	 * @since 3.3.0
	 */
	public static GeoPackage open(File file, boolean validate) {
		return open(file.getName(), file, validate);
	}

	/**
	 * Open a GeoPackage
	 * 
	 * @param name
	 *            GeoPackage name
	 * @param file
	 *            GeoPackage file
	 * @return GeoPackage
	 * @since 3.0.2
	 */
	public static GeoPackage open(String name, File file) {
		return open(name, file, true);
	}

	/**
	 * Open a GeoPackage
	 * 
	 * @param name
	 *            GeoPackage name
	 * @param file
	 *            GeoPackage file
	 * @param validate
	 *            validate the GeoPackage
	 * @return GeoPackage
	 * @since 3.3.0
	 */
	public static GeoPackage open(String name, File file, boolean validate) {

		// Check if the file exists
		File existingFile = existingFile(file);
		if (existingFile == null) {
			throw new GeoPackageException(
					"File not found: " + file.getAbsolutePath());
		}
		file = existingFile;

		// Validate the extension
		if (validate && GeoPackageIOUtils.hasFileExtension(file)) {
			GeoPackageValidate.validateGeoPackageExtension(file);
		}

		// Create the GeoPackage Connection and table creator
		GeoPackageConnection connection = connect(file);

		// Create a GeoPackage
		GeoPackage geoPackage = new GeoPackageImpl(name, file, connection);

		// Validate the GeoPackage has the minimum required tables
		if (validate) {
			try {
				GeoPackageValidate.validateMinimumTables(geoPackage);
			} catch (RuntimeException e) {
				geoPackage.close();
				throw e;
			}
		}

		return geoPackage;
	}

	/**
	 * Add a GeoPackage file extension to the file if it does not already
	 * contain a file extension
	 * 
	 * @param file
	 *            file
	 * @return original file or file with extension
	 * @since 4.0.0
	 */
	public static File addExtension(File file) {
		if (!GeoPackageIOUtils.hasFileExtension(file)) {
			file = GeoPackageIOUtils.addFileExtension(file,
					GeoPackageConstants.EXTENSION);
		}
		return file;
	}

	/**
	 * Check if the file exists in either its' current form or with a GeoPackage
	 * file extension, and return the existing file
	 * 
	 * @param file
	 *            file
	 * @return existing file or null if not file exists
	 * @since 4.0.0
	 */
	public static File existingFile(File file) {

		File existingFile = null;

		if (file.exists()) {
			existingFile = file;
		} else {
			file = addExtension(file);
			if (file.exists()) {
				existingFile = file;
			}
		}

		return existingFile;
	}

	/**
	 * Check if the file exists in either its' current form or with a GeoPackage
	 * file extension
	 * 
	 * @param file
	 *            file
	 * @return true if exists
	 * @since 4.0.0
	 */
	public static boolean exists(File file) {
		return existingFile(file) != null;
	}

	/**
	 * Connect to a GeoPackage file
	 * 
	 * @param file
	 *            GeoPackage file
	 * @return connection
	 */
	private static GeoPackageConnection connect(File file) {

		String databaseUrl = "jdbc:sqlite:" + file.getPath();

		// load the sqlite-JDBC driver using the current class loader
		try {
			Class.forName("org.sqlite.JDBC");
		} catch (ClassNotFoundException e) {
			throw new GeoPackageException(
					"Failed to load the SQLite JDBC driver", e);
		}

		// create a database connection
		Connection databaseConnection;
		try {
			databaseConnection = DriverManager.getConnection(databaseUrl);
		} catch (SQLException e) {
			throw new GeoPackageException(
					"Failed to get connection to the SQLite file: "
							+ file.getAbsolutePath(),
					e);
		}

		ConnectionSource connectionSource;
		try {
			connectionSource = new JdbcConnectionSource(databaseUrl);
		} catch (SQLException e) {
			throw new GeoPackageException(
					"Failed to get connection source to the SQLite file: "
							+ file.getAbsolutePath(),
					e);
		}

		// Create the GeoPackage Connection
		GeoPackageConnection connection = new GeoPackageConnection(file,
				databaseConnection, connectionSource);
		connection.enableForeignKeys();

		return connection;
	}

}

@@ -879,16 +879,65 @@
 ame());%0A
+%09%09if (LogBackendType.JAVA_UTIL.isAvailable()) %7B%0A%09
 %09%09Logger
@@ -989,16 +989,20 @@
 _UTIL);%0A
+%09%09%7D%0A
 %09%7D%0A%0A%09/**

check for java util log backend type availability