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

#include <memory>
#include <string>
#include <vector>
#include <map>
#include <boost/date_time/gregorian/gregorian.hpp>
#include "IoTDBRpcDataSet.h"
#include "Column.h"

class RowRecord {
public:
    int64_t timestamp;
    std::vector<Field> fields;

    explicit RowRecord(int64_t timestamp);
    RowRecord(int64_t timestamp, const std::vector<Field>& fields);
    explicit RowRecord(const std::vector<Field>& fields);
    RowRecord();

    void addField(const Field& f);
    std::string toString();
};

class SessionDataSet {
public:
    SessionDataSet(const std::string& sql,
                   const std::vector<std::string>& columnNameList,
                   const std::vector<std::string>& columnTypeList,
                   const std::map<std::string, int32_t>& columnNameIndex,
                   int64_t queryId,
                   int64_t statementId,
                   std::shared_ptr<IClientRPCServiceClient> client,
                   int64_t sessionId,
                   const std::vector<std::string>& queryResult,
                   bool ignoreTimestamp,
                   int64_t timeout,
                   bool moreData,
                   int32_t fetchSize,
                   const std::string& zoneId,
                   int32_t timeFactor,
                   std::vector<int32_t>& columnIndex2TsBlockColumnIndexList) {
        iotdbRpcDataSet_ = std::make_shared<IoTDBRpcDataSet>(sql,
                                                             columnNameList,
                                                             columnTypeList,
                                                             columnNameIndex,
                                                             ignoreTimestamp,
                                                             moreData,
                                                             queryId,
                                                             statementId,
                                                             client,
                                                             sessionId,
                                                             queryResult,
                                                             fetchSize,
                                                             timeout,
                                                             zoneId,
                                                             IoTDBRpcDataSet::DEFAULT_TIME_FORMAT,
                                                             timeFactor,
                                                             columnIndex2TsBlockColumnIndexList);
    }

    ~SessionDataSet() = default;

    bool hasNext();
    shared_ptr<RowRecord> next();

    int getFetchSize();
    void setFetchSize(int fetchSize);

    const std::vector<std::string>& getColumnNames() const;
    const std::vector<std::string>& getColumnTypeList() const;
    void closeOperationHandle(bool forceClose = false);

    class DataIterator {
        std::shared_ptr<IoTDBRpcDataSet> iotdbRpcDataSet_;

    public:
        DataIterator(std::shared_ptr<IoTDBRpcDataSet> iotdbRpcDataSet) :
            iotdbRpcDataSet_(iotdbRpcDataSet) {
        }

        bool next();

        bool isNull(const std::string& columnName);
        bool isNullByIndex(int32_t columnIndex);

        bool getBooleanByIndex(int32_t columnIndex);
        bool getBoolean(const std::string& columnName);

        double getDoubleByIndex(int32_t columnIndex);
        double getDouble(const std::string& columnName);

        float getFloatByIndex(int32_t columnIndex);
        float getFloat(const std::string& columnName);

        int32_t getIntByIndex(int32_t columnIndex);
        int32_t getInt(const std::string& columnName);

        int64_t getLongByIndex(int32_t columnIndex);
        int64_t getLong(const std::string& columnName);

        std::string getStringByIndex(int32_t columnIndex);
        std::string getString(const std::string& columnName);

        int64_t getTimestampByIndex(int32_t columnIndex);
        int64_t getTimestamp(const std::string& columnName);

        boost::gregorian::date getDateByIndex(int32_t columnIndex);
        boost::gregorian::date getDate(const std::string& columnName);

        int32_t findColumn(const std::string& columnName);
        const std::vector<std::string>& getColumnNames() const;
        const std::vector<std::string>& getColumnTypeList() const;
    };

    DataIterator getIterator() {
        return {iotdbRpcDataSet_};
    };

private:
    std::shared_ptr<RowRecord> constructRowRecordFromValueArray();

    std::shared_ptr<IoTDBRpcDataSet> iotdbRpcDataSet_;
};

#endif
