/**
* 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.
 */
#ifndef IOTDB_COMMON_H
#define IOTDB_COMMON_H

#include <string>
#include <vector>
#include <exception>

#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/protocol/TCompactProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportException.h>
#include <thrift/transport/TBufferTransports.h>
#include <boost/date_time/gregorian/gregorian.hpp>
#include <cstdint>
#include <boost/optional/optional.hpp>

#include "client_types.h"
#include "common_types.h"

using namespace std;

using ::apache::thrift::TException;
using ::apache::thrift::protocol::TBinaryProtocol;
using ::apache::thrift::protocol::TCompactProtocol;
using ::apache::thrift::transport::TBufferedTransport;
using ::apache::thrift::transport::TFramedTransport;
using ::apache::thrift::transport::TSocket;
using ::apache::thrift::transport::TTransport;
using ::apache::thrift::transport::TTransportException;

using namespace std;

constexpr int32_t EMPTY_DATE_INT = 10000101;

int32_t parseDateExpressionToInt(const boost::gregorian::date& date);
boost::gregorian::date parseIntToDate(int32_t dateInt);

std::string getTimePrecision(int32_t timeFactor);

std::string formatDatetime(const std::string& format, const std::string& precision,
                           int64_t timestamp, const std::string& zoneId);

std::tm convertToTimestamp(int64_t value, int32_t timeFactor);
std::tm int32ToDate(int32_t value);

namespace Version {
enum Version { V_0_12, V_0_13, V_1_0 };
}

namespace CompressionType {
enum CompressionType {
  UNCOMPRESSED = (char)0,
  SNAPPY = (char)1,
  GZIP = (char)2,
  LZO = (char)3,
  SDT = (char)4,
  PAA = (char)5,
  PLA = (char)6,
  LZ4 = (char)7,
  ZSTD = (char)8,
  LZMA2 = (char)9,
};
}

namespace TSDataType {
enum TSDataType {
  BOOLEAN = (char)0,
  INT32 = (char)1,
  INT64 = (char)2,
  FLOAT = (char)3,
  DOUBLE = (char)4,
  TEXT = (char)5,
  VECTOR = (char)6,
  UNKNOWN = (char)7,
  TIMESTAMP = (char)8,
  DATE = (char)9,
  BLOB = (char)10,
  STRING = (char)11,
  OBJECT = (char)12
};
}

TSDataType::TSDataType getDataTypeByStr(const std::string& typeStr);

namespace TSEncoding {
enum TSEncoding {
  PLAIN = (char)0,
  DICTIONARY = (char)1,
  RLE = (char)2,
  DIFF = (char)3,
  TS_2DIFF = (char)4,
  BITMAP = (char)5,
  GORILLA_V1 = (char)6,
  REGULAR = (char)7,
  GORILLA = (char)8,
  ZIGZAG = (char)9,
  FREQ = (char)10,
  INVALID_ENCODING = (char)255
};
}

namespace TSStatusCode {
enum TSStatusCode {
  SUCCESS_STATUS = 200,

  // System level
  INCOMPATIBLE_VERSION = 201,
  CONFIGURATION_ERROR = 202,
  START_UP_ERROR = 203,
  SHUT_DOWN_ERROR = 204,

  // General Error
  UNSUPPORTED_OPERATION = 300,
  EXECUTE_STATEMENT_ERROR = 301,
  MULTIPLE_ERROR = 302,
  ILLEGAL_PARAMETER = 303,
  OVERLAP_WITH_EXISTING_TASK = 304,
  INTERNAL_SERVER_ERROR = 305,

  // Client,
  REDIRECTION_RECOMMEND = 400,

  // Schema Engine
  DATABASE_NOT_EXIST = 500,
  DATABASE_ALREADY_EXISTS = 501,
  SERIES_OVERFLOW = 502,
  TIMESERIES_ALREADY_EXIST = 503,
  TIMESERIES_IN_BLACK_LIST = 504,
  ALIAS_ALREADY_EXIST = 505,
  PATH_ALREADY_EXIST = 506,
  METADATA_ERROR = 507,
  PATH_NOT_EXIST = 508,
  ILLEGAL_PATH = 509,
  CREATE_TEMPLATE_ERROR = 510,
  DUPLICATED_TEMPLATE = 511,
  UNDEFINED_TEMPLATE = 512,
  TEMPLATE_NOT_SET = 513,
  DIFFERENT_TEMPLATE = 514,
  TEMPLATE_IS_IN_USE = 515,
  TEMPLATE_INCOMPATIBLE = 516,
  SEGMENT_NOT_FOUND = 517,
  PAGE_OUT_OF_SPACE = 518,
  RECORD_DUPLICATED = 519,
  SEGMENT_OUT_OF_SPACE = 520,
  PBTREE_FILE_NOT_EXISTS = 521,
  OVERSIZE_RECORD = 522,
  PBTREE_FILE_REDO_LOG_BROKEN = 523,
  TEMPLATE_NOT_ACTIVATED = 524,

  // Storage Engine
  SYSTEM_READ_ONLY = 600,
  STORAGE_ENGINE_ERROR = 601,
  STORAGE_ENGINE_NOT_READY = 602,

  // Query Engine
  PLAN_FAILED_NETWORK_PARTITION = 721
};
}

class Field {
public:
  TSDataType::TSDataType dataType = TSDataType::UNKNOWN;
  boost::optional<bool> boolV;
  boost::optional<int> intV;
  boost::optional<boost::gregorian::date> dateV;
  boost::optional<int64_t> longV;
  boost::optional<float> floatV;
  boost::optional<double> doubleV;
  boost::optional<std::string> stringV;

  explicit Field(TSDataType::TSDataType a) {
    dataType = a;
  }

  Field() = default;

  /** True if this field is SQL NULL (optional for the active dataType is unset). Unknown types are treated as null. */
  bool isNull() const {
    switch (dataType) {
    case TSDataType::BOOLEAN:
      return !boolV.is_initialized();
    case TSDataType::INT32:
      return !intV.is_initialized();
    case TSDataType::INT64:
    case TSDataType::TIMESTAMP:
      return !longV.is_initialized();
    case TSDataType::FLOAT:
      return !floatV.is_initialized();
    case TSDataType::DOUBLE:
      return !doubleV.is_initialized();
    case TSDataType::TEXT:
    case TSDataType::STRING:
    case TSDataType::BLOB:
      return !stringV.is_initialized();
    case TSDataType::DATE:
      return !dateV.is_initialized();
    default:
      return true;
    }
  }
};

enum class ColumnCategory { TAG, FIELD, ATTRIBUTE };

class MyStringBuffer {
public:
  MyStringBuffer();
  explicit MyStringBuffer(const std::string& str);

  void reserve(size_t n);
  void clear();
  bool hasRemaining();
  int getInt();
  boost::gregorian::date getDate();
  int64_t getInt64();
  float getFloat();
  double getDouble();
  char getChar();
  bool getBool();
  std::string getString();

  void putInt(int ins);
  void putDate(boost::gregorian::date date);
  void putInt64(int64_t ins);
  void putFloat(float ins);
  void putDouble(double ins);
  void putChar(char ins);
  void putBool(bool ins);
  void putString(const std::string& ins);
  void concat(const std::string& ins);

public:
  std::string str;
  size_t pos;

private:
  void checkBigEndian();
  const char* getOrderedByte(size_t len);
  void putOrderedByte(char* buf, int len);

private:
  bool isBigEndian{};
  char numericBuf[8]{}; //only be used by int, long, float, double etc.
};

class BitMap {
public:
  explicit BitMap(size_t size = 0);
  void resize(size_t size);
  bool mark(size_t position);
  bool unmark(size_t position);
  void markAll();
  void reset();
  bool isMarked(size_t position) const;
  bool isAllUnmarked() const;
  bool isAllMarked() const;
  const std::vector<char>& getByteArray() const;
  size_t getSize() const;

private:
  size_t size;
  std::vector<char> bits;
};

class IoTDBException : public std::exception {
public:
  IoTDBException() = default;

  explicit IoTDBException(const std::string& m) : message(m) {}

  explicit IoTDBException(const char* m) : message(m) {}

  virtual const char* what() const noexcept override {
    return message.c_str();
  }

private:
  std::string message;
};

std::string extractExceptionMessage(const std::exception& exception);
std::string extractExceptionMessage(const std::exception_ptr& exceptionPtr);

class DateTimeParseException : public IoTDBException {
private:
  std::string parsedString;
  int errorIndex;

public:
  explicit DateTimeParseException(const std::string& message, std::string parsedData,
                                  int errorIndex)
      : IoTDBException(message), parsedString(std::move(parsedData)), errorIndex(errorIndex) {}

  explicit DateTimeParseException(const std::string& message, std::string parsedData,
                                  int errorIndex, const std::exception& cause)
      : IoTDBException(message + " [Caused by: " + cause.what() + "]"),
        parsedString(std::move(parsedData)), errorIndex(errorIndex) {}

  const std::string& getParsedString() const noexcept {
    return parsedString;
  }

  int getErrorIndex() const noexcept {
    return errorIndex;
  }

  const char* what() const noexcept override {
    static std::string fullMsg;
    fullMsg = std::string(IoTDBException::what()) + "\nParsed data: " + parsedString +
              "\nError index: " + std::to_string(errorIndex);
    return fullMsg.c_str();
  }
};

class IoTDBConnectionException : public IoTDBException {
public:
  IoTDBConnectionException() {}

  explicit IoTDBConnectionException(const char* m) : IoTDBException(m) {}

  explicit IoTDBConnectionException(const std::string& m) : IoTDBException(m) {}
};

class ExecutionException : public IoTDBException {
public:
  ExecutionException() {}

  explicit ExecutionException(const char* m) : IoTDBException(m) {}

  explicit ExecutionException(const std::string& m) : IoTDBException(m) {}

  explicit ExecutionException(const std::string& m, const TSStatus& tsStatus)
      : IoTDBException(m), status(tsStatus) {}

  TSStatus status;
};

class BatchExecutionException : public IoTDBException {
public:
  BatchExecutionException() {}

  explicit BatchExecutionException(const char* m) : IoTDBException(m) {}

  explicit BatchExecutionException(const std::string& m) : IoTDBException(m) {}

  explicit BatchExecutionException(const std::vector<TSStatus>& statusList)
      : statusList(statusList) {}

  BatchExecutionException(const std::string& m, const std::vector<TSStatus>& statusList)
      : IoTDBException(m), statusList(statusList) {}

  std::vector<TSStatus> statusList;
};

class RedirectException : public IoTDBException {
public:
  RedirectException() {}

  explicit RedirectException(const char* m) : IoTDBException(m) {}

  explicit RedirectException(const std::string& m) : IoTDBException(m) {}

  RedirectException(const std::string& m, const TEndPoint& endPoint)
      : IoTDBException(m), endPoint(endPoint) {}

  RedirectException(const std::string& m, const map<string, TEndPoint>& deviceEndPointMap)
      : IoTDBException(m), deviceEndPointMap(deviceEndPointMap) {}

  RedirectException(const std::string& m, const vector<TEndPoint>& endPointList)
      : IoTDBException(m), endPointList(endPointList) {}

  TEndPoint endPoint;
  map<string, TEndPoint> deviceEndPointMap;
  vector<TEndPoint> endPointList;
};

class UnSupportedDataTypeException : public IoTDBException {
public:
  UnSupportedDataTypeException() {}

  explicit UnSupportedDataTypeException(const char* m) : IoTDBException(m) {}

  explicit UnSupportedDataTypeException(const std::string& m)
      : IoTDBException("UnSupported dataType: " + m) {}
};

class SchemaNotFoundException : public IoTDBException {
public:
  SchemaNotFoundException() {}

  explicit SchemaNotFoundException(const char* m) : IoTDBException(m) {}

  explicit SchemaNotFoundException(const std::string& m) : IoTDBException(m) {}
};

class StatementExecutionException : public IoTDBException {
public:
  StatementExecutionException() {}

  explicit StatementExecutionException(const char* m) : IoTDBException(m) {}

  explicit StatementExecutionException(const std::string& m) : IoTDBException(m) {}
};

enum LogLevelType { LEVEL_DEBUG = 0, LEVEL_INFO, LEVEL_WARN, LEVEL_ERROR };

extern LogLevelType LOG_LEVEL;

#define log_debug(fmt, ...)                                                                        \
  do {                                                                                             \
    if (LOG_LEVEL <= LEVEL_DEBUG) {                                                                \
      string s = string("[DEBUG] %s:%d (%s) - ") + fmt + "\n";                                     \
      printf(s.c_str(), __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);                          \
    }                                                                                              \
  } while (0)
#define log_info(fmt, ...)                                                                         \
  do {                                                                                             \
    if (LOG_LEVEL <= LEVEL_INFO) {                                                                 \
      string s = string("[INFO]  %s:%d (%s) - ") + fmt + "\n";                                     \
      printf(s.c_str(), __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);                          \
    }                                                                                              \
  } while (0)
#define log_warn(fmt, ...)                                                                         \
  do {                                                                                             \
    if (LOG_LEVEL <= LEVEL_WARN) {                                                                 \
      string s = string("[WARN]  %s:%d (%s) - ") + fmt + "\n";                                     \
      printf(s.c_str(), __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);                          \
    }                                                                                              \
  } while (0)
#define log_error(fmt, ...)                                                                        \
  do {                                                                                             \
    if (LOG_LEVEL <= LEVEL_ERROR) {                                                                \
      string s = string("[ERROR] %s:%d (%s) - ") + fmt + "\n";                                     \
      printf(s.c_str(), __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__);                          \
    }                                                                                              \
  } while (0)

class RpcUtils {
public:
  std::shared_ptr<TSStatus> SUCCESS_STATUS;

  RpcUtils() {
    SUCCESS_STATUS = std::make_shared<TSStatus>();
    SUCCESS_STATUS->__set_code(TSStatusCode::SUCCESS_STATUS);
  }

  static void verifySuccess(const TSStatus& status);

  static void verifySuccessWithRedirection(const TSStatus& status);

  static void verifySuccessWithRedirectionForMultiDevices(const TSStatus& status,
                                                          vector<string> devices);

  static void verifySuccess(const std::vector<TSStatus>& statuses);

  static TSStatus getStatus(TSStatusCode::TSStatusCode tsStatusCode);

  static TSStatus getStatus(int code, const std::string& message);

  static std::shared_ptr<TSExecuteStatementResp>
  getTSExecuteStatementResp(TSStatusCode::TSStatusCode tsStatusCode);

  static std::shared_ptr<TSExecuteStatementResp>
  getTSExecuteStatementResp(TSStatusCode::TSStatusCode tsStatusCode, const std::string& message);

  static std::shared_ptr<TSExecuteStatementResp> getTSExecuteStatementResp(const TSStatus& status);

  static std::shared_ptr<TSFetchResultsResp>
  getTSFetchResultsResp(TSStatusCode::TSStatusCode tsStatusCode);

  static std::shared_ptr<TSFetchResultsResp>
  getTSFetchResultsResp(TSStatusCode::TSStatusCode tsStatusCode, const std::string& appendMessage);

  static std::shared_ptr<TSFetchResultsResp> getTSFetchResultsResp(const TSStatus& status);
};

class UrlUtils {
private:
  static const std::string PORT_SEPARATOR;
  static const std::string ABB_COLON;

  UrlUtils() = delete;
  ~UrlUtils() = delete;

public:
  /**
     * Parse TEndPoint from a given TEndPointUrl
     * example:[D80:0000:0000:0000:ABAA:0000:00C2:0002]:22227
     *
     * @param endPointUrl ip:port
     * @return TEndPoint with default values if parse error
     */
  static TEndPoint parseTEndPointIpv4AndIpv6Url(const std::string& endPointUrl);
};

#endif
