package info.archinnov.achilles.generated;

import com.datastax.driver.core.ConsistencyLevel;
import com.datastax.driver.core.DataType;
import com.datastax.driver.core.Row;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBiMap;
import com.google.common.reflect.TypeToken;
import info.archinnov.achilles.generated.function.List_String_Type;
import info.archinnov.achilles.generated.function.Long_Type;
import info.archinnov.achilles.generated.function.Map_Integer_String_Type;
import info.archinnov.achilles.generated.function.Map_String_String_Type;
import info.archinnov.achilles.generated.function.PartitionKeys_Type;
import info.archinnov.achilles.generated.function.Set_String_Type;
import info.archinnov.achilles.generated.function.String_Type;
import info.archinnov.achilles.generated.meta.entity.TestEntityWithComplexIndices_AchillesMeta.ColumnsForFunctions;
import info.archinnov.achilles.internals.apt.annotations.AchillesMeta;
import info.archinnov.achilles.internals.codec.FallThroughCodec;
import info.archinnov.achilles.internals.metamodel.AbstractEntityProperty;
import info.archinnov.achilles.internals.metamodel.AbstractProperty;
import info.archinnov.achilles.internals.metamodel.ListProperty;
import info.archinnov.achilles.internals.metamodel.MapProperty;
import info.archinnov.achilles.internals.metamodel.SetProperty;
import info.archinnov.achilles.internals.metamodel.SimpleProperty;
import info.archinnov.achilles.internals.metamodel.columns.ColumnInfo;
import info.archinnov.achilles.internals.metamodel.columns.ColumnType;
import info.archinnov.achilles.internals.metamodel.columns.FieldInfo;
import info.archinnov.achilles.internals.metamodel.columns.PartitionKeyInfo;
import info.archinnov.achilles.internals.metamodel.index.IndexInfo;
import info.archinnov.achilles.internals.metamodel.index.IndexType;
import info.archinnov.achilles.internals.sample_classes.parser.entity.TestEntityWithComplexIndices;
import info.archinnov.achilles.internals.strategy.naming.InternalNamingStrategy;
import info.archinnov.achilles.type.strategy.InsertStrategy;
import java.lang.Class;
import java.lang.Integer;
import java.lang.Long;
import java.lang.Override;
import java.lang.String;
import java.lang.SuppressWarnings;
import java.lang.UnsupportedOperationException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * Meta class of all entities of type TestEntityWithComplexIndices<br/>
 * The meta class is responsible for<br/>
 * <ul>
 *    <li>determining runtime consistency levels (read/write,serial)<li/>
 *    <li>determining runtime insert strategy<li/>
 *    <li>trigger event interceptors (if any)<li/>
 *    <li>map a Row back to an instance of TestEntityWithComplexIndices<li/>
 *    <li>determine runtime keyspace name using static annotations and runtime SchemaNameProvider (if any)<li/>
 *    <li>determine runtime table name using static annotations and runtime SchemaNameProvider (if any)<li/>
 *    <li>generate schema during bootstrap<li/>
 *    <li>validate schema during bootstrap<li/>
 *    <li>expose all property meta classes for encoding/decoding purpose on unitary columns<li/>
 * <ul/>
 */
@AchillesMeta
public final class TestEntityWithComplexIndices_AchillesMeta extends AbstractEntityProperty<TestEntityWithComplexIndices> {
  /**
   * Meta class for 'id' property <br/>
   * The meta class exposes some useful methods: <ul>
   *    <li>encodeFromJava: encode a property from raw Java to CQL java compatible type </li>
   *    <li>encodeField: extract the current property value from the given TestEntityWithComplexIndices instance and encode to CQL java compatible type </li>
   *    <li>decodeFromGettable: decode from a {@link com.datastax.driver.core.GettableData} instance (Row, UDTValue, TupleValue) the current property</li>
   * </ul>
   */
  @SuppressWarnings({"serial", "unchecked"})
  public static final SimpleProperty<TestEntityWithComplexIndices, Long, Long> id = new SimpleProperty<TestEntityWithComplexIndices, Long, Long>(new FieldInfo<>((TestEntityWithComplexIndices entity$) -> entity$.getId(), (TestEntityWithComplexIndices entity$, Long value$) -> entity$.setId(value$), "id", "id", ColumnType.PARTITION, new PartitionKeyInfo(1, false), IndexInfo.noIndex()), DataType.bigint(), gettableData$ -> gettableData$.get("id", java.lang.Long.class), (settableData$, value$) -> settableData$.set("id", value$, java.lang.Long.class), new TypeToken<Long>(){}, new TypeToken<Long>(){}, new FallThroughCodec<>(Long.class));

  /**
   * Meta class for 'simpleIndex' property <br/>
   * The meta class exposes some useful methods: <ul>
   *    <li>encodeFromJava: encode a property from raw Java to CQL java compatible type </li>
   *    <li>encodeField: extract the current property value from the given TestEntityWithComplexIndices instance and encode to CQL java compatible type </li>
   *    <li>decodeFromGettable: decode from a {@link com.datastax.driver.core.GettableData} instance (Row, UDTValue, TupleValue) the current property</li>
   * </ul>
   */
  @SuppressWarnings({"serial", "unchecked"})
  public static final SimpleProperty<TestEntityWithComplexIndices, String, String> simpleIndex = new SimpleProperty<TestEntityWithComplexIndices, String, String>(new FieldInfo<>((TestEntityWithComplexIndices entity$) -> entity$.getSimpleIndex(), (TestEntityWithComplexIndices entity$, String value$) -> entity$.setSimpleIndex(value$), "simpleIndex", "simpleindex", ColumnType.NORMAL, new ColumnInfo(false), IndexInfo.forNative(IndexType.NORMAL, "simpleindex_index", "", "")), DataType.text(), gettableData$ -> gettableData$.get("simpleindex", java.lang.String.class), (settableData$, value$) -> settableData$.set("simpleindex", value$, java.lang.String.class), new TypeToken<String>(){}, new TypeToken<String>(){}, new FallThroughCodec<>(String.class));

  /**
   * Meta class for 'collectionIndex' property <br/>
   * The meta class exposes some useful methods: <ul>
   *    <li>encodeFromJava: encode a property from raw Java to CQL java compatible type </li>
   *    <li>encodeField: extract the current property value from the given TestEntityWithComplexIndices instance and encode to CQL java compatible type </li>
   *    <li>decodeFromGettable: decode from a {@link com.datastax.driver.core.GettableData} instance (Row, UDTValue, TupleValue) the current property</li>
   * </ul>
   */
  @SuppressWarnings({"serial", "unchecked"})
  public static final ListProperty<TestEntityWithComplexIndices, String, String> collectionIndex = new ListProperty<>(new FieldInfo<>((TestEntityWithComplexIndices entity$) -> entity$.getCollectionIndex(), (TestEntityWithComplexIndices entity$, List<String> value$) -> entity$.setCollectionIndex(value$), "collectionIndex", "collectionindex", ColumnType.NORMAL, new ColumnInfo(false), IndexInfo.forNative(IndexType.COLLECTION, "collectionindex_index", "", "")), false, false, String.class, new SimpleProperty<TestEntityWithComplexIndices, String, String>(FieldInfo.<TestEntityWithComplexIndices, String> of("collectionIndex", "collectionindex", true), DataType.text(), gettable$ -> null, (udt$, value$) -> {}, new TypeToken<String>(){}, new TypeToken<String>(){}, new FallThroughCodec<>(String.class)));

  /**
   * Meta class for 'fullIndexOnCollection' property <br/>
   * The meta class exposes some useful methods: <ul>
   *    <li>encodeFromJava: encode a property from raw Java to CQL java compatible type </li>
   *    <li>encodeField: extract the current property value from the given TestEntityWithComplexIndices instance and encode to CQL java compatible type </li>
   *    <li>decodeFromGettable: decode from a {@link com.datastax.driver.core.GettableData} instance (Row, UDTValue, TupleValue) the current property</li>
   * </ul>
   */
  @SuppressWarnings({"serial", "unchecked"})
  public static final SetProperty<TestEntityWithComplexIndices, String, String> fullIndexOnCollection = new SetProperty<>(new FieldInfo<>((TestEntityWithComplexIndices entity$) -> entity$.getFullIndexOnCollection(), (TestEntityWithComplexIndices entity$, Set<String> value$) -> entity$.setFullIndexOnCollection(value$), "fullIndexOnCollection", "fullindexoncollection", ColumnType.NORMAL, new ColumnInfo(true), IndexInfo.forNative(IndexType.FULL, "fullindexoncollection_index", "", "")), true, false, String.class, new SimpleProperty<TestEntityWithComplexIndices, String, String>(FieldInfo.<TestEntityWithComplexIndices, String> of("fullIndexOnCollection", "fullindexoncollection", true), DataType.text(), gettable$ -> null, (udt$, value$) -> {}, new TypeToken<String>(){}, new TypeToken<String>(){}, new FallThroughCodec<>(String.class)));

  /**
   * Meta class for 'indexOnMapKey' property <br/>
   * The meta class exposes some useful methods: <ul>
   *    <li>encodeFromJava: encode a property from raw Java to CQL java compatible type </li>
   *    <li>encodeField: extract the current property value from the given TestEntityWithComplexIndices instance and encode to CQL java compatible type </li>
   *    <li>decodeFromGettable: decode from a {@link com.datastax.driver.core.GettableData} instance (Row, UDTValue, TupleValue) the current property</li>
   * </ul>
   */
  @SuppressWarnings({"serial", "unchecked"})
  public static final MapProperty<TestEntityWithComplexIndices, String, String, String, String> indexOnMapKey = new MapProperty<TestEntityWithComplexIndices, String, String, String, String>(new FieldInfo<>((TestEntityWithComplexIndices entity$) -> entity$.getIndexOnMapKey(), (TestEntityWithComplexIndices entity$, Map<String, String> value$) -> entity$.setIndexOnMapKey(value$), "indexOnMapKey", "indexonmapkey", ColumnType.NORMAL, new ColumnInfo(false), IndexInfo.forNative(IndexType.MAP_KEY, "indexonmapkey_index", "", "")), false, false, new SimpleProperty<TestEntityWithComplexIndices, String, String>(FieldInfo.<TestEntityWithComplexIndices, String> of("indexOnMapKey", "indexonmapkey", true), DataType.text(), gettable$ -> null, (udt$, value$) -> {}, new TypeToken<String>(){}, new TypeToken<String>(){}, new FallThroughCodec<>(String.class)), new SimpleProperty<TestEntityWithComplexIndices, String, String>(FieldInfo.<TestEntityWithComplexIndices, String> of("indexOnMapKey", "indexonmapkey", true), DataType.text(), gettable$ -> null, (udt$, value$) -> {}, new TypeToken<String>(){}, new TypeToken<String>(){}, new FallThroughCodec<>(String.class)));

  /**
   * Meta class for 'indexOnMapEntry' property <br/>
   * The meta class exposes some useful methods: <ul>
   *    <li>encodeFromJava: encode a property from raw Java to CQL java compatible type </li>
   *    <li>encodeField: extract the current property value from the given TestEntityWithComplexIndices instance and encode to CQL java compatible type </li>
   *    <li>decodeFromGettable: decode from a {@link com.datastax.driver.core.GettableData} instance (Row, UDTValue, TupleValue) the current property</li>
   * </ul>
   */
  @SuppressWarnings({"serial", "unchecked"})
  public static final MapProperty<TestEntityWithComplexIndices, Integer, Integer, String, String> indexOnMapEntry = new MapProperty<TestEntityWithComplexIndices, Integer, Integer, String, String>(new FieldInfo<>((TestEntityWithComplexIndices entity$) -> entity$.getIndexOnMapEntry(), (TestEntityWithComplexIndices entity$, Map<Integer, String> value$) -> entity$.setIndexOnMapEntry(value$), "indexOnMapEntry", "indexonmapentry", ColumnType.NORMAL, new ColumnInfo(false), IndexInfo.forNative(IndexType.MAP_ENTRY, "indexonmapentry_index", "", "")), false, false, new SimpleProperty<TestEntityWithComplexIndices, Integer, Integer>(FieldInfo.<TestEntityWithComplexIndices, Integer> of("indexOnMapEntry", "indexonmapentry", true), DataType.cint(), gettable$ -> null, (udt$, value$) -> {}, new TypeToken<Integer>(){}, new TypeToken<Integer>(){}, new FallThroughCodec<>(Integer.class)), new SimpleProperty<TestEntityWithComplexIndices, String, String>(FieldInfo.<TestEntityWithComplexIndices, String> of("indexOnMapEntry", "indexonmapentry", true), DataType.text(), gettable$ -> null, (udt$, value$) -> {}, new TypeToken<String>(){}, new TypeToken<String>(){}, new FallThroughCodec<>(String.class)));

  /**
   * Static class to expose "TestEntityWithComplexIndices_AchillesMeta" fields for <strong>type-safe</strong> function calls */
  public static final TestEntityWithComplexIndices_AchillesMeta.ColumnsForFunctions COLUMNS = new TestEntityWithComplexIndices_AchillesMeta.ColumnsForFunctions();
  ;

  @Override
  protected Class<TestEntityWithComplexIndices> getEntityClass() {
    return TestEntityWithComplexIndices.class;
  }

  @Override
  protected String getDerivedTableOrViewName() {
    return "testentitywithcomplexindices";
  }

  @Override
  protected BiMap<String, String> fieldNameToCqlColumn() {
    BiMap<String,String> map = HashBiMap.create(6);
    map.put("id", "id");
    map.put("simpleIndex", "simpleindex");
    map.put("collectionIndex", "collectionindex");
    map.put("fullIndexOnCollection", "fullindexoncollection");
    map.put("indexOnMapKey", "indexonmapkey");
    map.put("indexOnMapEntry", "indexonmapentry");
    return map;
  }

  @Override
  protected Optional<ConsistencyLevel> getStaticReadConsistency() {
    return Optional.empty();
  }

  @Override
  protected Optional<InternalNamingStrategy> getStaticNamingStrategy() {
    return Optional.empty();
  }

  @Override
  protected List<AbstractProperty<TestEntityWithComplexIndices, ?, ?>> getPartitionKeys() {
    return Arrays.asList(id);
  }

  @Override
  protected List<AbstractProperty<TestEntityWithComplexIndices, ?, ?>> getClusteringColumns() {
    return Arrays.asList();
  }

  @Override
  protected List<AbstractProperty<TestEntityWithComplexIndices, ?, ?>> getNormalColumns() {
    return Arrays.asList(collectionIndex,fullIndexOnCollection,indexOnMapEntry,indexOnMapKey,simpleIndex);
  }

  @Override
  protected List<AbstractProperty<TestEntityWithComplexIndices, ?, ?>> getComputedColumns() {
    return Arrays.asList();
  }

  @Override
  protected List<AbstractProperty<TestEntityWithComplexIndices, ?, ?>> getConstructorInjectedColumns() {
    return Arrays.asList();
  }

  @Override
  protected boolean isCounterTable() {
    return false;
  }

  @Override
  protected Optional<String> getStaticKeyspace() {
    return Optional.empty();
  }

  @Override
  protected Optional<String> getStaticTableOrViewName() {
    return Optional.empty();
  }

  @Override
  protected Optional<ConsistencyLevel> getStaticWriteConsistency() {
    return Optional.empty();
  }

  @Override
  protected Optional<ConsistencyLevel> getStaticSerialConsistency() {
    return Optional.empty();
  }

  @Override
  protected Optional<Integer> getStaticTTL() {
    return Optional.empty();
  }

  @Override
  protected Optional<InsertStrategy> getStaticInsertStrategy() {
    return Optional.empty();
  }

  @Override
  protected List<AbstractProperty<TestEntityWithComplexIndices, ?, ?>> getStaticColumns() {
    return Arrays.asList();
  }

  @Override
  protected List<AbstractProperty<TestEntityWithComplexIndices, ?, ?>> getCounterColumns() {
    return Arrays.asList();
  }

  @Override
  protected TestEntityWithComplexIndices newInstanceFromCustomConstructor(final Row row, final List<String> cqlColumns) {
    throw new UnsupportedOperationException("Cannot instantiate entity 'info.archinnov.achilles.internals.sample_classes.parser.entity.TestEntityWithComplexIndices' using custom constructor because no custom constructor (@EntityCreator) is defined");
  }

  /**
   * Utility class to expose all fields with their CQL type for function call */
  public static final class ColumnsForFunctions {
    /**
     * <br/>
     * Field to be used for <em>manager.dsl().select().function(...)</em> call
     * <br/>
     * This is an alias for the field <strong>"id"</strong> */
    public final Long_Type ID = new Long_Type(Optional.empty()){
      @Override
      protected String cqlColumn() {
          return "id";
    }
      @Override
      public boolean isFunctionCall() {
          return false;
    }
      }
    ;

    /**
     * <br/>
     * Field to be used for <em>manager.dsl().select().function(...)</em> call
     * <br/>
     * This is an alias for the field <strong>"simpleIndex"</strong> */
    public final String_Type SIMPLE_INDEX = new String_Type(Optional.empty()){
      @Override
      protected String cqlColumn() {
          return "simpleindex";
    }
      @Override
      public boolean isFunctionCall() {
          return false;
    }
      }
    ;

    /**
     * <br/>
     * Field to be used for <em>manager.dsl().select().function(...)</em> call
     * <br/>
     * This is an alias for the field <strong>"collectionIndex"</strong> */
    public final List_String_Type COLLECTION_INDEX = new List_String_Type(Optional.empty()){
      @Override
      protected String cqlColumn() {
          return "collectionindex";
    }
      @Override
      public boolean isFunctionCall() {
          return false;
    }
      }
    ;

    /**
     * <br/>
     * Field to be used for <em>manager.dsl().select().function(...)</em> call
     * <br/>
     * This is an alias for the field <strong>"fullIndexOnCollection"</strong> */
    public final Set_String_Type FULL_INDEX_ON_COLLECTION = new Set_String_Type(Optional.empty()){
      @Override
      protected String cqlColumn() {
          return "fullindexoncollection";
    }
      @Override
      public boolean isFunctionCall() {
          return false;
    }
      }
    ;

    /**
     * <br/>
     * Field to be used for <em>manager.dsl().select().function(...)</em> call
     * <br/>
     * This is an alias for the field <strong>"indexOnMapKey"</strong> */
    public final Map_String_String_Type INDEX_ON_MAP_KEY = new Map_String_String_Type(Optional.empty()){
      @Override
      protected String cqlColumn() {
          return "indexonmapkey";
    }
      @Override
      public boolean isFunctionCall() {
          return false;
    }
      }
    ;

    /**
     * <br/>
     * Field to be used for <em>manager.dsl().select().function(...)</em> call
     * <br/>
     * This is an alias for the field <strong>"indexOnMapEntry"</strong> */
    public final Map_Integer_String_Type INDEX_ON_MAP_ENTRY = new Map_Integer_String_Type(Optional.empty()){
      @Override
      protected String cqlColumn() {
          return "indexonmapentry";
    }
      @Override
      public boolean isFunctionCall() {
          return false;
    }
      }
    ;

    /**
     * <br/>
     * Field to be used with <em>SystemFunctions.token(xxx_AchillesMeta.COLUMNS.PARTITION_KEYS, "tokens")</em> call
     * <br/>
     */
    public final PartitionKeys_Type PARTITION_KEYS = new PartitionKeys_Type(new ArrayList<String>() {
     {
     add("id"); }
      })
    ;
  }
}