/*
 * Copyright DataStax, 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.datastax.oss.driver.internal.core.cql;

import com.datastax.oss.driver.api.core.CqlIdentifier;
import com.datastax.oss.driver.api.core.config.DriverConfigProfile;
import com.datastax.oss.driver.api.core.cql.PrepareRequest;
import com.datastax.oss.driver.api.core.cql.SimpleStatement;
import com.datastax.oss.driver.api.core.metadata.token.Token;
import java.nio.ByteBuffer;
import java.util.Map;

/**
 * For simplicity, this default implementation makes opinionated choices about {@code
 * *ForBoundStatements} methods: these should be appropriate for most cases, but not all use cases
 * are supported (for example, preparing with one profile and having the bound statements use
 * another profile is not possible). For exotic use cases, subclass or write your own
 * implementation.
 */
public class DefaultPrepareRequest implements PrepareRequest {

  private final SimpleStatement statement;

  public DefaultPrepareRequest(SimpleStatement statement) {
    this.statement = statement;
  }

  public DefaultPrepareRequest(String query) {
    this.statement = SimpleStatement.newInstance(query);
  }

  @Override
  public String getQuery() {
    return statement.getQuery();
  }

  @Override
  public String getConfigProfileName() {
    return statement.getConfigProfileName();
  }

  @Override
  public DriverConfigProfile getConfigProfile() {
    return statement.getConfigProfile();
  }

  @Override
  public CqlIdentifier getKeyspace() {
    return statement.getKeyspace();
  }

  @Override
  public CqlIdentifier getRoutingKeyspace() {
    // Prepare requests do not operate on a particular partition, token-aware routing doesn't apply.
    return null;
  }

  @Override
  public ByteBuffer getRoutingKey() {
    return null;
  }

  @Override
  public Token getRoutingToken() {
    return null;
  }

  @Override
  public Map<String, ByteBuffer> getCustomPayload() {
    return statement.getCustomPayload();
  }

  @Override
  public String getConfigProfileNameForBoundStatements() {
    return statement.getConfigProfileName();
  }

  @Override
  public DriverConfigProfile getConfigProfileForBoundStatements() {
    return statement.getConfigProfile();
  }

  @Override
  public Map<String, ByteBuffer> getCustomPayloadForBoundStatements() {
    return statement.getCustomPayload();
  }

  @Override
  public Boolean areBoundStatementsIdempotent() {
    return statement.isIdempotent();
  }
}

@@ -685,24 +685,76 @@
 Identifier;%0A
+import com.datastax.oss.driver.api.core.CqlSession;%0A
 import com.d
@@ -809,16 +809,16 @@
 rofile;%0A
-
 import c
@@ -1050,16 +1050,305 @@
 %0A/**%0A * 
+Default implementation of a prepare request, which is built internally to handle calls such as%0A * %7B@link CqlSession#prepare(String)%7D and %7B@link CqlSession#prepare(SimpleStatement)%7D.%0A *%0A * %3Cp%3EWhen a %7B@link SimpleStatement%7D gets prepared, some of its fields are propagated automatically.%0A * 
 For simp
@@ -1363,16 +1363,8 @@
 this
- default
  imp
@@ -1381,16 +1381,30 @@
 n makes 
+the following 
 opiniona
@@ -1418,142 +1418,810 @@
 ices
- about %7B@code%0A * *ForBoundStatements%7D methods: these should be appropriate for most cases, but not all use cases%0A * are supported
+:%0A *%0A * %3Cul%3E%0A *   %3Cli%3Ethe prepare request:%0A *       %3Cul%3E%0A *         %3Cli%3Ewill use the same configuration profile (or configuration profile name) as the %7B@code%0A *             SimpleStatement%7D;%0A *         %3Cli%3Ewill use the same custom payload as the %7B@code SimpleStatement%7D;%0A *       %3C/ul%3E%0A *   %3Cli%3Eany bound statement created from the prepared statement:%0A *       %3Cul%3E%0A *         %3Cli%3Ewill use the same configuration profile (or configuration profile name) as the %7B@code%0A *             SimpleStatement%7D;%0A *         %3Cli%3Ewill use the same custom payload as the %7B@code SimpleStatement%7D;%0A *         %3Cli%3Ewill be idempotent if and only if the %7B@code SimpleStatement%7D was idempotent.%0A *       %3C/ul%3E%0A * %3C/ul%3E%0A *%0A * %3Cp%3EThis should be appropriate for most use cases; however if you need something more exotic
  (for
+%0A *
  exa
@@ -2256,23 +2256,23 @@
 file
- and having the
+, but executing
  bou
@@ -2289,14 +2289,12 @@
 nts 
-use%0A *
+with
  ano
@@ -2302,100 +2302,141 @@
 her 
-profile is not possible). For exotic use cases, subclass or write your own%0A * implementation
+one), you can%0A * either write your own %7B@code PrepareRequest%7D implementation, or set the options manually on every%0A * bound statement
 .%0A *

Improve javadoc of DefaultPrepareRequest