// Copyright 2010 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.nosql;

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.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 com.google.gwtorm.server.StandardKeyEncoder;

/**
 * Base class for NoSQL typed databases.
 * <p>
 * Applications should use the database class to create instances of their
 * Schema extension interface, and thus open and connect to the 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 life of
 * the application.
 * <p>
 * Database instances are thread-safe, but returned Schema instances are not.
 * <p>
 * This class must be further extended by the NoSQL implementation to configure
 * the connectivity with the data store and supply the correct subclass of
 * {@link NoSqlSchema} that knows how to interact with the data store.
 *
 * @param <T> type of the application's Schema.
 * @param <S> type of the implementation's base for Schema implementations.
 * @param <A> type of the implementation's base for Access implementations.
 */
@SuppressWarnings("rawtypes")
public abstract class NoSqlDatabase<T extends Schema, S extends NoSqlSchema, A extends NoSqlAccess>
    implements SchemaFactory<T> {
  static {
    KeyUtil.setEncoderImpl(new StandardKeyEncoder());
  }

  private final SchemaModel schemaModel;
  private final SchemaFactory<T> implFactory;

  /**
   * Initialize a new database and generate the implementation.
   *
   * @param schemaBaseType class that the generated Schema implementation should
   *        extend in order to provide data store connectivity.
   * @param accessBaseType class that the generated Access implementations
   *        should extend in order to provide single-relation access for each
   *        schema instance.
   * @param appSchema the application schema interface that must be implemented
   *        and constructed on demand.
   * @throws OrmException the schema cannot be created because of an annotation
   *         error in the interface definitions.
   */
  protected NoSqlDatabase(final Class<S> schemaBaseType,
      final Class<A> accessBaseType, final Class<T> appSchema)
      throws OrmException {
    schemaModel = new JavaSchemaModel(appSchema);
    final GeneratedClassLoader loader = newLoader(appSchema);
    final Class<T> impl = generate(schemaBaseType, accessBaseType, loader);
    implFactory = new SchemaConstructorGen<>(loader, impl, this).create();
  }

  @Override
  public T open() throws OrmException {
    return implFactory.open();
  }

  /** @return the derived model of the application's schema. */
  public SchemaModel getSchemaModel() {
    return schemaModel;
  }

  @SuppressWarnings("unchecked")
  private Class<T> generate(final Class<S> schemaBaseType,
      final Class<A> accessBaseType, final GeneratedClassLoader loader)
      throws OrmException {
    return new SchemaGen(loader, schemaModel, getClass(), schemaBaseType,
        new SchemaGen.AccessGenerator() {
          @Override
          public Class<?> create(GeneratedClassLoader loader, RelationModel rm)
              throws OrmException {
            return new AccessGen(loader, rm, schemaBaseType, accessBaseType)
                .create();
          }
        }).create();
  }

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