/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.openjpa.conf;

import java.util.Properties;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.PersistenceException;

import org.apache.openjpa.persistence.OpenJPAPersistence;
import org.apache.openjpa.util.UserException;

import junit.framework.TestCase;

/**
 * Verifies appropriate exception is thrown when an incorrect protocol or
 * sub-protocol is specified in the JDBC URL. Per the JDBC specification, the
 * Driver should return a null connection upon getConnection() when a bad driver
 * is specified on the URL. OpenJPA must be able to handle this condition and
 * return an appropriate message.
 *
 * OpenJPA JIRA: {@link http://issues.apache.org/jira/browse/OPENJPA-656}
 *
 * @author Jeremy Bauer
 * @author Pinaki Poddar
 *
 */
public class TestBadJdbcUrl extends TestCase {
    public static final String GOOD_URL =
        "jdbc:derby:target/database/openjpa-derby-database;create=true";
    public static final String GOOD_DRIVER =
        "org.apache.derby.jdbc.EmbeddedDriver";
    public static final String GOOD_DATASOURCE =
        "org.apache.commons.dbcp2.BasicDataSource";

	public static final String BAD_DRIVER = "bad.driver";
	public static final String BAD_URL_PROTOCOL = "bad.url.protocol";
	public static final String BAD_URL_SUBPROTOCOL = "bad.url.sub.protocol";
    public static final String BAD_CONN_PROPS =
        "connectionUrl=bad,connectionDriver=bad";

	/*
	 * Test specifying URL with bad protocol but a valid Driver.
	 */
	public void testBadUrlProtocolValueWithValidDriverClass() {
		Properties p = new Properties();
		p.put("openjpa.ConnectionDriverName", GOOD_DRIVER);
		p.put("openjpa.ConnectionURL", BAD_URL_PROTOCOL);
		verifyConnectException(p, PersistenceException.class,
                UserException.class, GOOD_DRIVER, BAD_URL_PROTOCOL);
	}

	/*
	 * Test specifying URL with bad protocol but a valid DataSource.
	 */
	public void testBadUrlProtocolValueWithValidDataSource() {
		Properties p = new Properties();
		p.put("openjpa.ConnectionDriverName", GOOD_DATASOURCE);
		p.put("openjpa.ConnectionURL", BAD_URL_PROTOCOL);
		p.put("openjpa.ConnectionProperties", BAD_CONN_PROPS);
		verifyConnectException(p, PersistenceException.class,
				null, (String[])null);
	}

	/*
	 * Test specifying URL with bad sub-protocol but a valid Driver.
	 */
	public void testBadUrlSubprotocolValueWithValidDriverClass() {
		Properties p = new Properties();
		p.put("openjpa.ConnectionDriverName", GOOD_DRIVER);
		p.put("openjpa.ConnectionURL", BAD_URL_SUBPROTOCOL);
		verifyConnectException(p, PersistenceException.class,
                UserException.class, GOOD_DRIVER, BAD_URL_SUBPROTOCOL);
	}

	/*
	 * Test specifying URL with bad sub-protocol but a valid Driver.
	 */
	public void testBadUrlSubprotocolValueWithValidDataSource() {
		Properties p = new Properties();
		p.put("openjpa.ConnectionDriverName", GOOD_DRIVER);
		p.put("openjpa.ConnectionURL", BAD_URL_SUBPROTOCOL);
		verifyConnectException(p, PersistenceException.class,
                UserException.class, GOOD_DRIVER, BAD_URL_SUBPROTOCOL);
	}

	/*
	 * Test specifying Valid URL with an invalid Driver.
	 */
	public void testValidUrlWithInvalidDriver() {
		Properties p = new Properties();
		p.put("openjpa.ConnectionDriverName", BAD_DRIVER);
		p.put("openjpa.ConnectionURL", GOOD_URL);
		verifyConnectException(p, PersistenceException.class,
				UserException.class, GOOD_URL, BAD_DRIVER);
	}

	/**
     * Attempts to connect with given properties and analyze exception for the
	 * existence of given target exception and error message strings.
	 *
	 * @param props
	 *            the properties to initialize the persistence unit
	 * @param target
	 *            the type expected exception to be raised.
	 * @param nested
     *            the type expected nested exception. null implies not to look
	 *            for any.
	 * @param keys
	 *            the strings that must occur in the exception message.
	 */
	private void verifyConnectException(Properties props, Class targetType,
			Class nestedType, String... keys) {
		EntityManagerFactory emf = null;
		EntityManager em = null;
		try {
            emf = Persistence.createEntityManagerFactory("test", props);
			em = emf.createEntityManager();
			OpenJPAPersistence.cast(em).getConnection();
			fail("Should have caught a " + targetType.getName());
		} catch (Throwable t) {
			assertException(t, targetType, nestedType);
			assertMessage(t, keys);
		} finally {
			if (em != null)
				em.close();
			if (emf != null)
				emf.close();
		}
	}

	/**
     * Asserts that the given targetType is assignable from actual. Asserts that
	 * the nestedType is a nested within the given actual Throwable
	 *
	 * @param actual
	 * @param targetType
	 * @param nestedType
	 */
	void assertException(final Throwable actual, Class targetType,
			Class nestedTargetType) {
		if (targetType == null)
			return;
		assertNotNull(actual);
		Class actualType = actual.getClass();
		if (!targetType.isAssignableFrom(actualType)) {
			fail(targetType.getName() + " is not assignable from "
					+ actualType.getName());
		}

		if (nestedTargetType != null) {
			Throwable nested = actual.getCause();
            Class nestedType = (nested == null) ? null : nested.getClass();
			while (nestedType != null) {
                if (nestedType.isAssignableFrom(nestedTargetType)) {
					return;
				} else {
					Throwable next = nested.getCause();
					if (next == null || next == nested)
						break;
					nestedType = next.getClass();
					nested     = next;
				}
			}
            fail("No nested type " + nestedTargetType + " in " + actual);
		}
	}

	/**
     * Assert that each of given keys are present in the message of the given
	 * Throwable.
	 */
	void assertMessage(Throwable actual, String... keys) {
		if (actual == null || keys == null)
			return;
		String message = actual.getMessage();
		for (String key : keys) {
            assertTrue(key + " is not in " + message, message.contains(key));
		}
	}
}
