/*
 * 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.logging.log4j.jdbc.appender;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.junit.LoggerContextRule;
import org.junit.rules.TestRule;
import org.junit.runner.Description;

/**
 * JUnit rule to set up a database. This will create a table using the configure creation statement on startup, run its
 * wrapped test(s), then execute a drop table statement on shutdown, and finally will attempt execute a {@code SHUTDOWN}
 * command afterward (e.g., for H2, HSQLDB). When used in integration tests, this rule should be the outer rule in a
 * chain with {@link LoggerContextRule}.
 *
 * @since 2.8
 */
public class JdbcRule implements TestRule {

	private final ConnectionSource connectionSource;
	private final String createTableStatement;
	private final String dropTableStatement;

	/**
	 * Creates a JdbcRule using a {@link ConnectionSource} and a table creation statement.
	 *
	 * @param connectionSource a required source for obtaining a Connection.
	 * @param createTableStatement an optional SQL DDL statement to create a table for use in a JUnit test.
	 * @param dropTableStatement an optional SQL DDL statement to drop the created table.
	 */
	public JdbcRule(final ConnectionSource connectionSource, final String createTableStatement,
			final String dropTableStatement) {
		this.connectionSource = Objects.requireNonNull(connectionSource, "connectionSource");
		this.createTableStatement = createTableStatement;
		this.dropTableStatement = dropTableStatement;
	}

	@Override
	public org.junit.runners.model.Statement apply(final org.junit.runners.model.Statement base,
			final Description description) {
		return new org.junit.runners.model.Statement() {
			@Override
			public void evaluate() throws Throwable {
				try (final Connection connection = getConnection();
						final Statement statement = connection.createStatement()) {
					try {
						if (StringUtils.isNotEmpty(createTableStatement)) {
							statement.executeUpdate(createTableStatement);
						}
						base.evaluate();
					} finally {
						if (StringUtils.isNotEmpty(dropTableStatement)) {
							statement.executeUpdate(dropTableStatement);
						}
						statement.execute("SHUTDOWN");
					}
				}
			}

		};
	}

	public Connection getConnection() throws SQLException {
		return connectionSource.getConnection();
	}

	public ConnectionSource getConnectionSource() {
		return connectionSource;
	}
}
