/**
* 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) {
        iotdbRpcDataSet_ = std::make_shared<IoTDBRpcDataSet>(sql,
                                                             columnNameList,
                                                             columnTypeList,
                                                             columnNameIndex,
                                                             ignoreTimestamp,
                                                             moreData,
                                                             queryId,
                                                             statementId,
                                                             client,
                                                             sessionId,
                                                             queryResult,
                                                             fetchSize,
                                                             timeout,
                                                             zoneId,
                                                             IoTDBRpcDataSet::DEFAULT_TIME_FORMAT);
    }

    ~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
