/*
  Copyright (c) 2014 DataStax

  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.
*/

#include "batch_request.hpp"
#include "types.hpp"
#include "serialization.hpp"
#include "statement.hpp"
#include "execute_request.hpp"

extern "C" {

CassBatch* cass_batch_new(CassBatchType type) {
  cass::BatchRequest* batch = new cass::BatchRequest(type);
  batch->retain();
  return CassBatch::to(batch);
}

void cass_batch_free(CassBatch* batch) {
  batch->release();
}

CassError cass_batch_set_consistency(CassBatch* batch,
                                CassConsistency consistency) {
  batch->set_consistency(consistency);
  return CASS_OK;
}

CassError cass_batch_add_statement(CassBatch* batch, CassStatement* statement) {
  batch->add_statement(statement);
  return CASS_OK;
}

} // extern "C"

namespace cass {

int BatchRequest::encode(int version, BufferVec* bufs) const {
  if (version != 2) {
    return ENCODE_ERROR_UNSUPPORTED_PROTOCOL;
  }
  return encode_v2(bufs);
}

int BatchRequest::encode_v2(BufferVec* bufs) const {
  const int version = 2;

  size_t length = 0;

  {
    // <type> [byte] + <n> [short]
    size_t buf_size = sizeof(uint8_t) + sizeof(uint16_t);

    Buffer buf(buf_size);
    size_t pos = buf.encode_byte(0, type_);
    buf.encode_uint16(pos, statements().size());

    bufs->push_back(buf);
    length += buf_size;
  }

  for (BatchRequest::StatementList::const_iterator
       it = statements_.begin(),
       end = statements_.end();
       it != end; ++it) {
    const Statement* statement = *it;

    // <kind> [byte]
    int buf_size = sizeof(uint8_t);

    // <string_or_id> [long string] | [short bytes]
    buf_size += (statement->kind() == CASS_BATCH_KIND_QUERY) ? sizeof(int32_t) : sizeof(uint16_t);
    buf_size += statement->query().size();

    // <n><value_1>...<value_n>
    buf_size += sizeof(uint16_t); // <n> [short]

    bufs->push_back(Buffer(buf_size));
    length += buf_size;

    Buffer& buf = bufs->back();
    size_t pos = buf.encode_byte(0, statement->kind());

    if (statement->kind() == CASS_BATCH_KIND_QUERY) {
      pos = buf.encode_long_string(pos,
                                 statement->query().data(),
                                 statement->query().size());
    } else {
      pos = buf.encode_string(pos,
                              statement->query().data(),
                              statement->query().size());
    }

    buf.encode_uint16(pos, statement->values_count());
    if (statement->values_count() > 0) {
      length += statement->encode_values(version, bufs);
    }
  }

  {
    // <consistency> [short]
    size_t buf_size = sizeof(uint16_t);

    Buffer buf(buf_size);
    buf.encode_uint16(0, consistency_);
    bufs->push_back(buf);
    length += buf_size;
  }

  return length;
}

BatchRequest::~BatchRequest() {
  for (StatementList::iterator it = statements_.begin(),
                               end = statements_.end();
       it != end; ++it) {
    (*it)->release();
  }
}

void BatchRequest::add_statement(Statement* statement) {
  if (statement->kind() == 1) {
    ExecuteRequest* execute_request = static_cast<ExecuteRequest*>(statement);
    prepared_statements_[execute_request->prepared_id()] = execute_request;
  }
  statement->retain();
  statements_.push_back(statement);
}

bool BatchRequest::prepared_statement(const std::string& id,
                                      std::string* statement) const {
  PreparedMap::const_iterator it = prepared_statements_.find(id);
  if (it != prepared_statements_.end()) {
    *statement = it->second->prepared_statement();
    return true;
  }
  return false;
}

} // namespace cass
