// Copyright (C) 2009 The Android Open Source Project
//
// Licensed 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 com.google.gerrit.testutil;

import com.google.gerrit.reviewdb.CurrentSchemaVersion;
import com.google.gerrit.reviewdb.ReviewDb;
import com.google.gerrit.reviewdb.SystemConfig;
import com.google.gerrit.server.config.SystemConfigProvider;
import com.google.gerrit.server.schema.Current;
import com.google.gerrit.server.schema.SchemaCreator;
import com.google.gerrit.server.schema.SchemaVersion;
import com.google.gwtorm.client.OrmException;
import com.google.gwtorm.client.SchemaFactory;
import com.google.gwtorm.jdbc.Database;
import com.google.gwtorm.jdbc.SimpleDataSource;
import com.google.inject.Guice;
import com.google.inject.Key;
import com.google.inject.Provider;

import junit.framework.TestCase;

import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

/**
 * An in-memory test instance of {@link ReviewDb} database.
 * <p>
 * Test classes should create one instance of this class for each unique test
 * database they want to use. When the tests needing this instance are complete,
 * ensure that {@link #drop(InMemoryDatabase)} is called to free the resources so
 * the JVM running the unit tests doesn't run out of heap space.
 */
public class InMemoryDatabase implements SchemaFactory<ReviewDb> {
  private static int dbCnt;

  private static synchronized DataSource newDataSource() throws SQLException {
    final Properties p = new Properties();
    p.setProperty("driver", org.h2.Driver.class.getName());
    p.setProperty("url", "jdbc:h2:mem:" + "Test_" + (++dbCnt));
    final DataSource dataSource = new SimpleDataSource(p);
    return dataSource;
  }

  /** Drop the database from memory; does nothing if the instance was null. */
  public static void drop(final InMemoryDatabase db) {
    if (db != null) {
      db.drop();
    }
  }

  private Connection openHandle;
  private Database<ReviewDb> database;
  private boolean created;
  private SchemaVersion schemaVersion;

  public InMemoryDatabase() throws OrmException {
    try {
      final DataSource dataSource = newDataSource();

      // Open one connection. This will peg the database into memory
      // until someone calls drop on us, allowing subsequent connections
      // opened against the same URL to go to the same set of tables.
      //
      openHandle = dataSource.getConnection();

      // Build the access layer around the connection factory.
      //
      database = new Database<ReviewDb>(dataSource, ReviewDb.class);

      schemaVersion =
          Guice.createInjector(new SchemaVersion.Module()).getBinding(
              Key.get(SchemaVersion.class, Current.class)).getProvider().get();
    } catch (SQLException e) {
      throw new OrmException(e);
    }
  }

  public Database<ReviewDb> getDatabase() {
    return database;
  }

  @Override
  public ReviewDb open() throws OrmException {
    return getDatabase().open();
  }

  /** Ensure the database schema has been created and initialized. */
  public InMemoryDatabase create() throws OrmException {
    if (!created) {
      created = true;
      final ReviewDb c = open();
      try {
        new SchemaCreator(new File("."), schemaVersion).create(c);
      } finally {
        c.close();
      }
    }
    return this;
  }

  /** Drop this database from memory so it no longer exists. */
  public void drop() {
    if (openHandle != null) {
      try {
        openHandle.close();
      } catch (SQLException e) {
        System.err.println("WARNING: Cannot close database connection");
        e.printStackTrace(System.err);
      }
      openHandle = null;
      database = null;
    }
  }

  public SystemConfig getSystemConfig() {
    return new SystemConfigProvider(this, new Provider<SchemaVersion>() {
      public SchemaVersion get() {
        return schemaVersion;
      }
    }).get();
  }

  public CurrentSchemaVersion getSchemaVersion() throws OrmException {
    final ReviewDb c = open();
    try {
      return c.schemaVersion().get(new CurrentSchemaVersion.Key());
    } finally {
      c.close();
    }
  }

  public void assertSchemaVersion() throws OrmException {
    final CurrentSchemaVersion act = getSchemaVersion();
    TestCase.assertEquals(schemaVersion.getVersionNbr(), act.versionNbr);
  }
}
