/*
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements.  See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership.  The ASF licenses this file
  to you 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 "dse_polygon.hpp"
#include "dse_validate.hpp"

#include <assert.h>
#include <iomanip>
#include <sstream>

using namespace datastax;
using namespace datastax::internal;
using namespace datastax::internal::core;
using namespace datastax::internal::enterprise;

extern "C" {

DsePolygon* dse_polygon_new() { return DsePolygon::to(new enterprise::Polygon()); }

void dse_polygon_free(DsePolygon* polygon) { delete polygon->from(); }

void dse_polygon_reset(DsePolygon* polygon) { polygon->reset(); }

void dse_polygon_reserve(DsePolygon* polygon, cass_uint32_t num_rings,
                         cass_uint32_t total_num_points) {
  polygon->reserve(num_rings, total_num_points);
}

CassError dse_polygon_start_ring(DsePolygon* polygon) { return polygon->start_ring(); }

CassError dse_polygon_add_point(DsePolygon* polygon, cass_double_t x, cass_double_t y) {
  polygon->add_point(x, y);
  return CASS_OK;
}

CassError dse_polygon_finish(DsePolygon* polygon) { return polygon->finish(); }

DsePolygonIterator* dse_polygon_iterator_new() {
  return DsePolygonIterator::to(new PolygonIterator());
}

CassError dse_polygon_iterator_reset(DsePolygonIterator* iterator, const CassValue* value) {
  return iterator->reset_binary(value);
}

CassError dse_polygon_iterator_reset_with_wkt_n(DsePolygonIterator* iterator, const char* wkt,
                                                size_t wkt_length) {
  return iterator->reset_text(wkt, wkt_length);
}

CassError dse_polygon_iterator_reset_with_wkt(DsePolygonIterator* iterator, const char* wkt) {
  return dse_polygon_iterator_reset_with_wkt_n(iterator, wkt, SAFE_STRLEN(wkt));
}

void dse_polygon_iterator_free(DsePolygonIterator* iterator) { delete iterator->from(); }

cass_uint32_t dse_polygon_iterator_num_rings(const DsePolygonIterator* iterator) {
  return iterator->num_rings();
}

CassError dse_polygon_iterator_next_num_points(DsePolygonIterator* iterator,
                                               cass_uint32_t* num_points) {
  return iterator->next_num_points(num_points);
}

CassError dse_polygon_iterator_next_point(DsePolygonIterator* iterator, cass_double_t* x,
                                          cass_double_t* y) {
  return iterator->next_point(x, y);
}

} // extern "C"

String Polygon::to_wkt() const {
  // Special case empty polygon
  if (num_rings_ == 0) {
    return "POLYGON EMPTY";
  }

  OStringStream ss;
  ss.precision(WKT_MAX_DIGITS);
  ss << "POLYGON (";
  const cass_byte_t* pos = bytes_.data() + WKB_HEADER_SIZE + sizeof(cass_uint32_t);
  for (cass_uint32_t i = 0; i < num_rings_; ++i) {
    if (i > 0) ss << ", ";
    ss << "(";
    cass_uint32_t num_points = decode_uint32(pos, native_byte_order());
    pos += sizeof(cass_uint32_t);
    for (cass_uint32_t j = 0; j < num_points; ++j) {
      if (j > 0) ss << ", ";
      ss << decode_double(pos, native_byte_order());
      pos += sizeof(cass_double_t);
      ss << " ";
      ss << decode_double(pos, native_byte_order());
      pos += sizeof(cass_double_t);
    }
    ss << ")";
  }
  ss << ")";
  return ss.str();
}

CassError PolygonIterator::reset_binary(const CassValue* value) {
  size_t size;
  const cass_byte_t* pos;
  WkbByteOrder byte_order;
  cass_uint32_t num_rings;

  CassError rc = validate_data_type(value, DSE_POLYGON_TYPE);
  if (rc != CASS_OK) return rc;

  rc = cass_value_get_bytes(value, &pos, &size);
  if (rc != CASS_OK) return rc;

  if (size < WKB_POLYGON_HEADER_SIZE) {
    return CASS_ERROR_LIB_NOT_ENOUGH_DATA;
  }
  size -= WKB_POLYGON_HEADER_SIZE;

  if (decode_header(pos, &byte_order) != WKB_GEOMETRY_TYPE_POLYGON) {
    return CASS_ERROR_LIB_INVALID_DATA;
  }
  pos += WKB_HEADER_SIZE;

  num_rings = decode_uint32(pos, byte_order);
  pos += sizeof(cass_uint32_t);

  const cass_byte_t* rings = pos;
  const cass_byte_t* rings_end = pos + size;

  for (cass_uint32_t i = 0; i < num_rings; ++i) {
    cass_uint32_t num_points;

    if (size < sizeof(cass_uint32_t)) {
      return CASS_ERROR_LIB_NOT_ENOUGH_DATA;
    }
    size -= sizeof(cass_uint32_t);

    num_points = decode_uint32(pos, byte_order);
    pos += sizeof(cass_uint32_t);

    if (size < 2 * num_points * sizeof(cass_double_t)) {
      return CASS_ERROR_LIB_NOT_ENOUGH_DATA;
    }
    size -= 2 * num_points * sizeof(cass_double_t);
  }

  num_rings_ = num_rings;
  binary_iterator_ = BinaryIterator(rings, rings_end, byte_order);
  iterator_ = &binary_iterator_;

  return CASS_OK;
}

CassError PolygonIterator::reset_text(const char* text, size_t size) {
  cass_uint32_t num_rings = 0;
  const bool skip_numbers = true;
  WktLexer lexer(text, size, skip_numbers);

  if (lexer.next_token() != WktLexer::TK_TYPE_POLYGON) {
    return CASS_ERROR_LIB_BAD_PARAMS;
  }

  // Validate format and count the number of rings
  WktLexer::Token token = lexer.next_token();

  // Special case "POLYGON EMPTY"
  if (token == WktLexer::TK_EMPTY) {
    return CASS_OK;
  }

  if (token != WktLexer::TK_OPEN_PAREN) {
    return CASS_ERROR_LIB_BAD_PARAMS;
  }

  token = lexer.next_token();
  while (token != WktLexer::TK_EOF && token != WktLexer::TK_CLOSE_PAREN) {
    // Start ring
    if (token != WktLexer::TK_OPEN_PAREN) {
      return CASS_ERROR_LIB_BAD_PARAMS;
    }

    // Consume points in ring
    token = lexer.next_token();
    while (token != WktLexer::TK_EOF && token != WktLexer::TK_CLOSE_PAREN) {
      // First number in point
      if (token != WktLexer::TK_NUMBER) {
        return CASS_ERROR_LIB_BAD_PARAMS;
      }

      // Second number in point
      token = lexer.next_token();
      if (token != WktLexer::TK_NUMBER) {
        return CASS_ERROR_LIB_BAD_PARAMS;
      }

      // Check and skip "," token
      token = lexer.next_token();
      if (token == WktLexer::TK_COMMA) {
        token = lexer.next_token();
        // Verify there are more points
        if (token != WktLexer::TK_NUMBER) {
          return CASS_ERROR_LIB_BAD_PARAMS;
        }
      }
    }

    // End ring
    if (token != WktLexer::TK_CLOSE_PAREN) {
      return CASS_ERROR_LIB_BAD_PARAMS;
    }

    ++num_rings;

    // Check and skip "," token
    token = lexer.next_token();
    if (token == WktLexer::TK_COMMA) {
      token = lexer.next_token();
      // Verify there are more rings
      if (token != WktLexer::TK_OPEN_PAREN) {
        return CASS_ERROR_LIB_BAD_PARAMS;
      }
    }
  }

  // Validate closing ")"
  if (token != WktLexer::TK_CLOSE_PAREN) {
    return CASS_ERROR_LIB_BAD_PARAMS;
  }

  num_rings_ = num_rings;
  text_iterator_ = TextIterator(text, size);
  iterator_ = &text_iterator_;

  return CASS_OK;
}

CassError PolygonIterator::BinaryIterator::next_num_points(cass_uint32_t* num_points) {
  if (state_ != STATE_NUM_POINTS) {
    return CASS_ERROR_LIB_INVALID_STATE;
  }

  uint32_t n = *num_points = decode_uint32(position_, byte_order_);
  position_ += sizeof(cass_uint32_t);
  points_end_ = position_ + n * 2 * sizeof(cass_double_t);
  state_ = STATE_POINTS;

  return CASS_OK;
}

CassError PolygonIterator::BinaryIterator::next_point(cass_double_t* x, cass_double_t* y) {
  if (state_ != STATE_POINTS) {
    return CASS_ERROR_LIB_INVALID_STATE;
  }

  *x = decode_double(position_, byte_order_);
  position_ += sizeof(cass_double_t);
  *y = decode_double(position_, byte_order_);
  position_ += sizeof(cass_double_t);
  if (position_ >= rings_end_) {
    state_ = STATE_DONE;
  } else if (position_ >= points_end_) {
    state_ = STATE_NUM_POINTS;
  }

  return CASS_OK;
}

PolygonIterator::TextIterator::TextIterator(const char* text, size_t size)
    : state_(STATE_NUM_POINTS)
    , lexer_(text, size) {
  WktLexer::Token token;
  UNUSED_(token);
  // Skip over "POLYGON (" tokens
  token = lexer_.next_token();
  assert(token == WktLexer::TK_TYPE_POLYGON);
  token = lexer_.next_token();
  assert(token == WktLexer::TK_OPEN_PAREN);
}

CassError PolygonIterator::TextIterator::next_num_points(cass_uint32_t* num_points) {
  WktLexer::Token token;
  token = lexer_.next_token();

  *num_points = 0;

  // If we're at the end of the text this will return WktLexer::TK_EOF
  if (state_ != STATE_NUM_POINTS || token != WktLexer::TK_OPEN_PAREN) {
    return CASS_ERROR_LIB_INVALID_STATE;
  }

  const bool skip_numbers = true;
  WktLexer temp(lexer_, skip_numbers); // Read forward using a temp lexer

  token = temp.next_token();
  while (token != WktLexer::TK_EOF && token != WktLexer::TK_CLOSE_PAREN) {
    // First number in point
    assert(token == WktLexer::TK_NUMBER);

    // Second number in point
    token = temp.next_token();
    assert(token == WktLexer::TK_NUMBER);

    ++(*num_points);

    // Check and skip "," token
    token = temp.next_token();
    if (token == WktLexer::TK_COMMA) {
      token = temp.next_token();
      assert(token == WktLexer::TK_NUMBER);
    }
  }

  assert(token == WktLexer::TK_CLOSE_PAREN);
  state_ = STATE_POINTS;

  return CASS_OK;
}

CassError PolygonIterator::TextIterator::next_point(cass_double_t* x, cass_double_t* y) {
  WktLexer::Token token;

  if (state_ != STATE_POINTS) {
    return CASS_ERROR_LIB_INVALID_STATE;
  }

  // First number in point
  token = lexer_.next_token();
  assert(token == WktLexer::TK_NUMBER);
  *x = lexer_.number();

  // Second number in point
  token = lexer_.next_token();
  assert(token == WktLexer::TK_NUMBER);
  *y = lexer_.number();

  token = lexer_.next_token();
  if (token == WktLexer::TK_CLOSE_PAREN) {
    // Done with this ring
    token = lexer_.next_token();
    if (token == WktLexer::TK_CLOSE_PAREN) {
      // Done with last ring
      state_ = STATE_DONE;
    } else {
      // More rings
      assert(token == WktLexer::TK_COMMA);
      state_ = STATE_NUM_POINTS;
    }
  } else {
    // More points
    assert(token == WktLexer::TK_COMMA);
  }

  return CASS_OK;
}
