// Copyright 2008 Google Inc.
//
// 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.gwtorm.jdbc;

import com.google.gwtorm.client.KeyUtil;
import com.google.gwtorm.schema.RelationModel;
import com.google.gwtorm.schema.SchemaModel;
import com.google.gwtorm.schema.java.JavaSchemaModel;
import com.google.gwtorm.schema.sql.SqlDialect;
import com.google.gwtorm.server.GeneratedClassLoader;
import com.google.gwtorm.server.OrmException;
import com.google.gwtorm.server.Schema;
import com.google.gwtorm.server.SchemaConstructorGen;
import com.google.gwtorm.server.SchemaFactory;
import com.google.gwtorm.server.SchemaGen;
import java.sql.Connection;
import java.sql.SQLException;
import javax.sql.DataSource;

/**
 * Constructor for application {@link Schema} extensions.
 *
 * <p>Applications should use the Database class to create instances of their Schema extension
 * interface, and thus open and connect to the JDBC data store.
 *
 * <p>Creating a new Database instance is expensive, due to the type analysis and code generation
 * performed to implement the Schema and Access interfaces. Applications should create and cache
 * their Database instance for the live of the application.
 *
 * <p>Database instances are thread-safe, but returned Schema instances are not.
 *
 * @param <T>
 */
public class Database<T extends Schema> implements SchemaFactory<T> {

  private final DataSource dataSource;
  private final JavaSchemaModel schemaModel;
  private final SchemaFactory<T> implFactory;
  private final SqlDialect implDialect;

  /**
   * Create a new database interface, generating the interface implementations.
   *
   * @param ds JDBC connection information
   * @param schema application extension of the Schema interface to implement.
   * @throws OrmException the schema interface is incorrectly defined, or the driver class is not
   *     available through the current class loader.
   */
  public Database(final DataSource ds, final Class<T> schema) throws OrmException {
    dataSource = ds;

    SqlDialect dialect;
    try {
      Connection c = ds.getConnection();
      try {
        dialect = SqlDialect.getDialectFor(c);
      } finally {
        c.close();
      }
    } catch (SQLException e) {
      throw new OrmException("Unable to determine SqlDialect", e);
    }

    schemaModel = new JavaSchemaModel(schema);
    final GeneratedClassLoader loader = newLoader(schema);
    final Class<T> impl = generate(dialect, loader);
    implFactory = new SchemaConstructorGen<>(loader, impl, this).create();
    implDialect = dialect;
  }

  @SuppressWarnings({"unchecked", "rawtypes"})
  private Class<T> generate(final SqlDialect dialect, final GeneratedClassLoader loader)
      throws OrmException {
    return new SchemaGen(
            loader,
            schemaModel,
            getClass(),
            JdbcSchema.class,
            new SchemaGen.AccessGenerator() {
              @Override
              public Class<?> create(GeneratedClassLoader loader, RelationModel rm)
                  throws OrmException {
                return new AccessGen(loader, rm, dialect).create();
              }
            })
        .create();
  }

  SqlDialect getDialect() {
    return implDialect;
  }

  SchemaModel getSchemaModel() {
    return schemaModel;
  }

  /**
   * Open a new connection to the database and get a Schema wrapper.
   *
   * @return a new JDBC connection, wrapped up in the application's Schema.
   * @throws OrmException the connection could not be opened to the database. The JDBC exception
   *     detail should be examined to determine the root cause of the connection failure.
   */
  @Override
  public T open() throws OrmException {
    return implFactory.open();
  }

  Connection newConnection() throws OrmException {
    final Connection conn;
    try {
      conn = dataSource.getConnection();
    } catch (SQLException e) {
      throw new OrmException("Cannot open database connection", e);
    }

    try {
      if (!conn.getAutoCommit()) {
        conn.setAutoCommit(true);
      }
    } catch (SQLException e) {
      try {
        conn.close();
      } catch (SQLException e2) {
      }
      throw new OrmException("Cannot force auto-commit on connection", e);
    }
    return conn;
  }

  private static <T> GeneratedClassLoader newLoader(final Class<T> schema) {
    return new GeneratedClassLoader(schema.getClassLoader());
  }
}
