/*******************************************************************************
 * Copyright (c) 2006 - 2007 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.db.tests.internal.platforms;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.NoSuchElementException;
import java.util.Properties;

import junit.framework.Assert;
import junit.framework.TestCase;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.datatools.connectivity.ConnectionProfileException;
import org.eclipse.datatools.connectivity.IConnectionProfile;
import org.eclipse.datatools.connectivity.ProfileManager;
import org.eclipse.datatools.connectivity.db.generic.IDBDriverDefinitionConstants;
import org.eclipse.datatools.connectivity.drivers.IDriverMgmtConstants;
import org.eclipse.datatools.connectivity.drivers.IPropertySet;
import org.eclipse.datatools.connectivity.drivers.PropertySetImpl;
import org.eclipse.datatools.connectivity.drivers.XMLFileManager;
import org.eclipse.datatools.connectivity.internal.ConnectivityPlugin;
import org.eclipse.jpt.db.internal.ConnectionProfile;
import org.eclipse.jpt.db.internal.ConnectionProfileRepository;
import org.eclipse.jpt.db.internal.DTPConnectionProfileWrapper;
import org.eclipse.jpt.db.internal.Database;
import org.eclipse.jpt.db.internal.Schema;
import org.eclipse.jpt.db.internal.Table;
import org.eclipse.jpt.db.tests.internal.JptDbTestsPlugin;
import org.eclipse.jpt.utility.internal.CollectionTools;
import org.eclipse.jpt.utility.internal.StringTools;

/**
 *  Base class for all supported DTP platform.
 */
public abstract class DTPPlatformTests extends TestCase {

    protected ConnectionProfileRepository connectionRepository;
    
    private Properties platformProperties;
	private String currentDbVendor;
	private String currentDbVersion;

	private static final String PLATFORM_CONFIG_DIRECTORY = "config";	//$NON-NLS-1$
	
	private static final String PROFILE_NAME_PROPERTY = "profileName";	//$NON-NLS-1$
	private static final String PROFILE_DESCRIPTION_PROPERTY = "profileDescription";	//$NON-NLS-1$
	private static final String USER_NAME_PROPERTY = "userName";	//$NON-NLS-1$
	private static final String USER_PASSWORD_PROPERTY = "userPassword";	//$NON-NLS-1$
	private static final String DB_DRIVER_JAR_PROPERTY = "databasedriverJarList";	//$NON-NLS-1$
	private static final String DB_NAME_PROPERTY = "databaseName";	//$NON-NLS-1$
	private static final String DB_URL_PROPERTY = "databaseUrl";	//$NON-NLS-1$
	
	private static final String PROFILE_NAME_DEFAULT = "jpatest";	//$NON-NLS-1$
	private static final String PROFILE_DESCRIPTION_DEFAULT = "JDBC Profile for JPA Testing";	//$NON-NLS-1$
	private static final String USER_NAME_DEFAULT = "userName";	//$NON-NLS-1$
	private static final String USER_PASSWORD_DEFAULT = "";	//$NON-NLS-1$
	private static final String DB_NAME_DEFAULT = "testdb";	//$NON-NLS-1$
	
	private static final String MISSING_PROPERTY_MESSAGE = "Enter missing property in platform config file (config/database.properties)";	

    public DTPPlatformTests( String name) {
        super( name);
        
        this.connectionRepository = ConnectionProfileRepository.instance();
    }

	protected void setUp() throws Exception {
        super.setUp();
        this.connectionRepository.initializeListeners();
        
        if( this.platformIsNew()) {
        	this.loadPlatformProperties();
        	
        	this.buildDriverDefinitionFile( IDriverMgmtConstants.DRIVER_FILE);
        	this.buildConnectionProfile( this.profileName());
        	this.currentDbVendor = this.databaseVendor();
        	this.currentDbVersion = this.databaseVersion();
        }
        this.verifyProfileNamed( this.profileName());
	}

	protected void tearDown() throws Exception {
        super.tearDown();
        
        this.connectionRepository.disposeListeners();
	}

	// ********** tests **********

	public void testConnection() throws Exception {

		this.connect();
		
        this.verifyDatabaseVersionNumber();
        this.verifyDatabaseContent();

        this.disconnect();
    }
    
	public void testGetProfiles() {
		// Getting the profile directly from DTP ProfileManager
		IConnectionProfile[] profiles = ProfileManager.getInstance().getProfiles();
		Assert.assertNotNull( profiles);
		Assert.assertTrue( profiles.length > 0);
	}

	public void testGetProfilesByProvider() {
		// Get Profiles By ProviderID
		IConnectionProfile[] profiles = ProfileManager.getInstance().getProfileByProviderID( this.getProfile().getProviderId());
		Assert.assertNotNull( profiles);
		Assert.assertTrue( profiles.length > 0);
	}
	
	public void testGetProfileByName() {
		// Get Profile By Name
		IConnectionProfile dtpProfile = this.getDTPProfile();
		Assert.assertNotNull( dtpProfile);
		Assert.assertTrue( dtpProfile.getName().equals( this.profileName()));
	}
	
	public void testGetProfileByInstanceId() {
		// Get Profile By InstanceID
		IConnectionProfile dtpProfile = ProfileManager.getInstance().getProfileByInstanceID( this.getProfile().getInstanceId());
		Assert.assertNotNull( dtpProfile);
		Assert.assertTrue( dtpProfile.getName().equals( this.profileName()));
	}

	public void testWorkingOffline() {
		
		if( this.getProfile().supportsWorkOfflineMode()) {

			if( ! this.getProfile().canWorkOffline()) {
				this.connect();
				this.saveWorkOfflineData();
				this.disconnect();
				
				Assert.assertTrue( this.getProfile().canWorkOffline());
			}
			this.workOffline();
			
			Assert.assertTrue( this.getProfile().isConnected());
			Assert.assertTrue( this.getProfile().isWorkingOffline());

			this.disconnect();
		}
	}
		
	// ********** internal tests **********

    private void verifyDatabaseVersionNumber() {
    	Database database = this.getProfile().getDatabase();
    	Assert.assertNotNull( database);
    	
        String actualVersionNumber = database.getVersion();
        String expectedVersionNumber = this.databaseVersion();
        String errorMessage = "Expected version number: " + expectedVersionNumber + " but the actual version number was: " + actualVersionNumber;
        assertTrue( errorMessage, actualVersionNumber.indexOf( expectedVersionNumber) != -1);

        String actualVendor = database.getVendor();
        String expectedVendor = this.databaseVendor();
        errorMessage = "Expected vendor: " + expectedVendor + " but the actual vendor was: " + actualVendor;
        assertEquals( errorMessage, actualVendor, expectedVendor);
    }
    
    private void verifyDatabaseContent() {
    	Database database = this.getProfile().getDatabase();
    	Assert.assertTrue( database.schemataSize() > 0);
		
        Schema schema = database.schemaNamed( this.getProfile().getUserName());
		if( schema != null) {
			Assert.assertTrue( schema.sequencesSize() >= 0);
			
			Object[] tableNames = CollectionTools.array( schema.tableNames());
			if( tableNames.length >= 1) {
				Table table = schema.tableNamed(( String)tableNames[ 0]);
				Assert.assertTrue( table.columnsSize() >= 0);
				Assert.assertTrue( table.foreignKeyColumnsSize() >= 0);
				Assert.assertTrue( table.foreignKeysSize() >= 0);
				Assert.assertTrue( table.primaryKeyColumnsSize() >= 0);
			}
		}
    }

    private void verifyProfileNamed( String profileName) {
    	
    	ConnectionProfile profile = this.getProfileNamed( profileName);
    	Assert.assertTrue( "ConnectionProfile not found", profileName.equals( profile.getName()));
    }

	// ***** Platform specific behavior *****

    protected abstract String databaseVendor();
    protected abstract String databaseVersion();

    protected abstract String driverName();
    protected abstract String driverDefinitionType();
    protected abstract String driverDefinitionId();
    protected abstract String driverClass();

    protected abstract String getConfigName();

	// ***** Behavior *****

    protected void connect() {

        this.getProfile().connect();
		Assert.assertTrue( "Could not connect.", this.getProfile().isConnected());
		Assert.assertFalse( "Connection corrupted.", this.getProfile().isWorkingOffline());
    }
    
    protected void disconnect() {
    	
    	this.getProfile().disconnect();
        Assert.assertFalse( "Disconnect failed.", this.getProfile().isConnected());
    }

	private void workOffline() {
		IStatus status = this.getProfile().workOffline();

		Assert.assertTrue( "Could not work offline.", status.isOK());
	}

	private void saveWorkOfflineData() {
		IStatus status = this.getProfile().saveWorkOfflineData();

		Assert.assertTrue( "Could not save offline data.", status.isOK());
	}
    
	// ********** queries **********

    protected Schema getSchemaNamed( String schemaName) { 

	    return this.getProfile().getDatabase().schemaNamed( schemaName);
    }
	
    protected Collection<Table> getTables() {
		
        Schema schema = this.getSchemaNamed( this.getProfile().getUserName());
		if( schema == null) {
			return new ArrayList<Table>();
		}
		return CollectionTools.collection( schema.tables());
    }

    protected Table getTableNamed( String tableName) { 

	    Schema schema =  this.getSchemaNamed( this.getProfile().getUserName());
	    Assert.assertNotNull( schema);
	
		return schema.tableNamed( tableName);
    }

    protected String providerId() {
        return DTPConnectionProfileWrapper.CONNECTION_PROFILE_TYPE;
    }
     
    protected String passwordIsSaved() {
        return "true";
    }


    protected IConnectionProfile getDTPProfile() {
		return ProfileManager.getInstance().getProfileByName( this.profileName());
    }
	
    protected String profileName() {
    	return this.platformProperties.getProperty( PROFILE_NAME_PROPERTY, PROFILE_NAME_DEFAULT);
    }    
    
    protected String profileDescription() {
    	return this.platformProperties.getProperty( PROFILE_DESCRIPTION_PROPERTY, PROFILE_DESCRIPTION_DEFAULT);
    }    
    
    protected String userName() {
    	return this.platformProperties.getProperty( USER_NAME_PROPERTY, USER_NAME_DEFAULT);
    }
    
    protected String userPassword() {
    	return this.platformProperties.getProperty( USER_PASSWORD_PROPERTY, USER_PASSWORD_DEFAULT);
    }    
    
    protected String databaseName() {
    	return this.platformProperties.getProperty( DB_NAME_PROPERTY, DB_NAME_DEFAULT);
    }
    
    protected String databasedriverJarList() {
    	String dbDriverJarList = this.platformProperties.getProperty( DB_DRIVER_JAR_PROPERTY);
    	if ( StringTools.stringIsEmpty( dbDriverJarList)) {
    		throw new NoSuchElementException( MISSING_PROPERTY_MESSAGE);
    	}
    	return dbDriverJarList;
    }
    
    protected String databaseUrl() {
    	String dbUrl = this.platformProperties.getProperty( DB_URL_PROPERTY);
    	if ( StringTools.stringIsEmpty( dbUrl)) {
    		throw new NoSuchElementException( MISSING_PROPERTY_MESSAGE);
    	}
    	return dbUrl;
    }

    protected ConnectionProfile getProfile() {

    	return this.getProfileNamed( this.profileName());
    }

    protected ConnectionProfile getProfileNamed( String profileName) {
    	
    	return ConnectionProfileRepository.instance().profileNamed( profileName);
    }
   
    private String getTestPluginBundleId() {
		return JptDbTestsPlugin.BUNDLE_ID;
	}

	private IPath getDriverDefinitionLocation() {
		return ConnectivityPlugin.getDefault().getStateLocation();
	}
	
	private String getConfigPath() {
    	return this.getConfigDir() + "/" + this.getConfigName();
    }
	
	private String getConfigDir() {
    	return PLATFORM_CONFIG_DIRECTORY;
    }

	private boolean platformIsNew() {
		return( !this.databaseVendor().equals( this.currentDbVendor) || this.databaseVersion().equals( this.currentDbVersion));
	}
	
    private void loadPlatformProperties() throws IOException {
		
		if( this.platformProperties == null) {
			URL configUrl = Platform.getBundle( this.getTestPluginBundleId()).getEntry( this.getConfigPath());

			this.platformProperties = new Properties();
			this.platformProperties.load( configUrl.openStream());
		}
	}
	
	private Properties buildDriverProperties() {
		Properties driverProperties = new Properties();
		driverProperties.setProperty( DTPConnectionProfileWrapper.DRIVER_DEFINITION_TYPE_PROP_ID, this.driverDefinitionType());
		driverProperties.setProperty( DTPConnectionProfileWrapper.DRIVER_JAR_LIST_PROP_ID, this.databasedriverJarList());
		driverProperties.setProperty( IDBDriverDefinitionConstants.USERNAME_PROP_ID, this.userName());
		driverProperties.setProperty( IDBDriverDefinitionConstants.DRIVER_CLASS_PROP_ID, this.driverClass());
		driverProperties.setProperty( IDBDriverDefinitionConstants.DATABASE_NAME_PROP_ID, this.databaseName());
		driverProperties.setProperty( IDBDriverDefinitionConstants.PASSWORD_PROP_ID, this.userPassword());
		driverProperties.setProperty( IDBDriverDefinitionConstants.URL_PROP_ID, this.databaseUrl());
		driverProperties.setProperty( IDBDriverDefinitionConstants.DATABASE_VENDOR_PROP_ID, this.databaseVendor());
		driverProperties.setProperty( IDBDriverDefinitionConstants.DATABASE_VERSION_PROP_ID, this.databaseVersion());
		return driverProperties;
	}

	private Properties buildBasicProperties() {
		Properties basicProperties = new Properties();
		basicProperties.setProperty( IDBDriverDefinitionConstants.DATABASE_NAME_PROP_ID, this.databaseName());
		basicProperties.setProperty( IDBDriverDefinitionConstants.USERNAME_PROP_ID, this.userName());
		basicProperties.setProperty( IDBDriverDefinitionConstants.PASSWORD_PROP_ID, this.userPassword());
		basicProperties.setProperty( DTPConnectionProfileWrapper.DRIVER_DEFINITION_PROP_ID, this.driverDefinitionId());
		
		basicProperties.setProperty( IDBDriverDefinitionConstants.DRIVER_CLASS_PROP_ID, this.driverClass());
		basicProperties.setProperty( IDBDriverDefinitionConstants.URL_PROP_ID, this.databaseUrl());
		basicProperties.setProperty( IDBDriverDefinitionConstants.DATABASE_VENDOR_PROP_ID, this.databaseVendor());
		basicProperties.setProperty( IDBDriverDefinitionConstants.DATABASE_VERSION_PROP_ID, this.databaseVersion());
		
		basicProperties.setProperty( DTPConnectionProfileWrapper.DATABASE_SAVE_PWD_PROP_ID, this.passwordIsSaved());
		return basicProperties;
	}

	private void buildConnectionProfile( String profileName) throws ConnectionProfileException {
		
		ProfileManager profileManager = ProfileManager.getInstance();
		Assert.assertNotNull( profileManager);
		
		IConnectionProfile dtpProfile = this.getDTPProfile();
		if( dtpProfile == null) {
			Properties basicProperties = buildBasicProperties();
			ProfileManager.getInstance().createProfile( profileName, this.profileDescription(), this.providerId(), basicProperties);
		}
	}

	private void buildDriverDefinitionFile( String driverFileName) throws CoreException {
		
		XMLFileManager.setStorageLocation( this.getDriverDefinitionLocation());
		XMLFileManager.setFileName( driverFileName);
		IPropertySet[] propsets = new IPropertySet[ 1];
		String driverName = this.driverName();
		String driverId = this.driverDefinitionId();
		PropertySetImpl propertySet = new PropertySetImpl( driverName, driverId);
		propertySet.setProperties( driverId, this.buildDriverProperties());
		propsets[ 0] = propertySet;

		XMLFileManager.saveNamedPropertySet( propsets);
		
		File driverDefinitioneFile =  this.getDriverDefinitionLocation().append( driverFileName).toFile();
		Assert.assertTrue( driverDefinitioneFile.exists());
	}
	
}
