/*
 * 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 UTILS_UTILS_H
#define UTILS_UTILS_H

#include <stdint.h>
#include <stdio.h>
#include <string.h>  // memcpy
#include <sys/time.h>

#include <iostream>
#include <sstream>
#include <string>

#include "common/allocator/my_string.h"
#include "common/db_common.h"
#include "utils/util_define.h"

namespace common {
extern TSEncoding get_value_encoder(TSDataType data_type);
extern CompressionType get_default_compressor();
/**
 * @brief Represents the schema information for a single measurement.
 * @brief Represents the category of a column in a table schema.
 *
 * This enumeration class defines the supported categories for columns within a
 * table schema, distinguishing between tag and field columns.
 */
enum class ColumnCategory { TAG = 0, FIELD = 1, ATTRIBUTE = 2, TIME = 3 };

/**
 * @brief Represents the schema information for a single column.
 *
 * This structure holds the metadata necessary to describe how a specific column
 * is stored, including its name, data type, category.
 */
struct ColumnSchema {
    std::string column_name_;
    TSDataType data_type_;
    CompressionType compression_;
    TSEncoding encoding_;
    ColumnCategory column_category_;

    ColumnSchema()
        : column_name_(""),
          data_type_(INVALID_DATATYPE),
          compression_(UNCOMPRESSED),
          encoding_(PLAIN),
          column_category_(ColumnCategory::FIELD) {}

    /**
     * @brief Constructs a ColumnSchema object with the given parameters.
     *
     * @param column_name The name of the column. Must be a non-empty string.
     *                    This name is used to identify the column within the
     * table.
     * @param data_type The data type of the measurement, such as INT32, DOUBLE,
     * TEXT, etc. This determines how the data will be stored and interpreted.
     * @param column_category The category of the column indicating its role or
     * type within the schema, e.g., FIELD, TAG. Defaults to
     * ColumnCategory::FIELD if not specified.
     * @note It is the responsibility of the caller to ensure that `column_name`
     * is not empty.
     */
    ColumnSchema(std::string column_name, TSDataType data_type,
                 CompressionType compression, TSEncoding encoding,
                 ColumnCategory column_category = ColumnCategory::FIELD)
        : column_name_(std::move(column_name)),
          data_type_(data_type),
          compression_(compression),
          encoding_(encoding),
          column_category_(column_category) {}

    ColumnSchema(std::string column_name, TSDataType data_type,
                 ColumnCategory column_category = ColumnCategory::FIELD)
        : column_name_(std::move(column_name)),
          data_type_(data_type),
          compression_(get_default_compressor()),
          encoding_(get_value_encoder(data_type)),
          column_category_(column_category) {}

    const std::string& get_column_name() const { return column_name_; }
    const TSDataType& get_data_type() const { return data_type_; }
    const ColumnCategory& get_column_category() const {
        return column_category_;
    }
    const CompressionType& get_compression() const { return compression_; }
    const TSEncoding& get_encoding() const { return encoding_; }
    bool operator==(const ColumnSchema& other) const {
        return (data_type_ == other.data_type_ &&
                encoding_ == other.encoding_ &&
                compression_ == other.compression_ &&
                column_name_ == other.column_name_);
    }

    bool operator!=(const ColumnSchema& other) const {
        return (data_type_ != other.data_type_ ||
                encoding_ != other.encoding_ ||
                compression_ != other.compression_ ||
                column_name_ != other.column_name_);
    }

    bool is_valid() const {
        return data_type_ != INVALID_DATATYPE &&
               encoding_ != INVALID_ENCODING &&
               compression_ != INVALID_COMPRESSION;
    }

    void reset() {
        // TODO
    }

    void get_device_name(char* ret_device_name_buf, const int buf_len,
                         uint32_t& ret_len) const {
        int pos = column_name_.find_last_of('.');
        ASSERT(pos > 0 && pos < buf_len);
        memcpy(ret_device_name_buf, column_name_.c_str(), pos);
        ret_device_name_buf[pos] = '\0';
        ret_len = pos;
    }
    std::string get_device_name_str() const {
        int pos = column_name_.find_last_of('.');
        ASSERT(pos > 0);
        return column_name_.substr(0, pos);
    }
    void get_device_name(String& device_name) const {
        int pos = column_name_.find_last_of('.');
        ASSERT(pos > 0);
        const char* c_string = column_name_.c_str();
        device_name.buf_ = (char*)c_string;
        device_name.len_ = pos;
    }
    void get_measurement_name(char* ret_measurement_name_buf, const int buf_len,
                              uint32_t& ret_len) const {
        int pos = column_name_.find_last_of('.');
        ASSERT(pos > 0 && pos < buf_len);
        ret_len = column_name_.size() - pos - 1;
        memcpy(ret_measurement_name_buf, column_name_.c_str() + pos + 1,
               ret_len);
        ret_measurement_name_buf[ret_len] = '\0';
    }
    std::string get_measurement_name_str() const {
        int pos = column_name_.find_last_of('.');
        ASSERT(pos > 0);
        return column_name_.substr(pos + 1, column_name_.size() - pos);
    }
    // TODO remove
    void get_measurement_name(String& measurement_name) const {
        int pos = column_name_.find_last_of('.');
        ASSERT(pos > 0);
        const char* c_string = column_name_.c_str();
        measurement_name.buf_ = (char*)c_string + pos + 1;
        measurement_name.len_ = column_name_.size() - pos - 1;
    }
    String get_measurement_name() {
        int pos = column_name_.find_last_of('.');
        ASSERT(pos > 0);
        const char* c_string = column_name_.c_str();
        String res;
        res.buf_ = (char*)c_string + pos + 1;
        res.len_ = column_name_.size() - pos - 1;
        return res;
    }

#ifdef DEBUG
    std::string debug_string()  // for debug
    {
        std::stringstream out;
        out << "print ColumnSchema: " << this << std::endl
            << "name: " << column_name_.c_str() << std::endl
            << "datatype: " << get_data_type_name(data_type_) << std::endl
            << "encoding: " << get_encoding_name(encoding_) << std::endl
            << "compression:" << get_compression_name(compression_)
            << std::endl;
        return out.str();
    }
#endif
};

FORCE_INLINE int64_t get_cur_timestamp() {
    int64_t timestamp = 0;
    struct timeval tv;
    if (gettimeofday(&tv, NULL) >= 0) {
        timestamp = (int64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000;
    }
    return timestamp;
}
}  // end namespace common

#endif  // UTILS_UTILS_H
