/*
 * 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.
 */

package client

import (
	"github.com/apache/iotdb-client-go/rpc"
)

const (
	TimestampColumnName = "Time"
)

type SessionDataSet struct {
	ioTDBRpcDataSet *IoTDBRpcDataSet
}

// Next prepares the next result row for reading,
// returns true on success, or false if there is no next result row or an error
// appened while preparing it.
// consulted Err should be consulted to distinguish between the two cases.
// This is not goroutine safe
func (s *SessionDataSet) Next() (bool, error) {
	return s.ioTDBRpcDataSet.next()
}

// GetText returns string value of column value on row.
// This is not goroutine safe
func (s *SessionDataSet) GetText(columnName string) string {
	return s.ioTDBRpcDataSet.getText(columnName)
}

func (s *SessionDataSet) GetBool(columnName string) bool {
	return s.ioTDBRpcDataSet.getBool(columnName)
}

func (s *SessionDataSet) Scan(dest ...interface{}) error {
	return s.ioTDBRpcDataSet.scan(dest...)
}

func (s *SessionDataSet) GetFloat(columnName string) float32 {
	return s.ioTDBRpcDataSet.getFloat(columnName)
}

func (s *SessionDataSet) GetDouble(columnName string) float64 {
	return s.ioTDBRpcDataSet.getDouble(columnName)
}

func (s *SessionDataSet) GetInt32(columnName string) int32 {
	return s.ioTDBRpcDataSet.getInt32(columnName)
}

func (s *SessionDataSet) GetInt64(columnName string) int64 {
	return s.ioTDBRpcDataSet.getInt64(columnName)
}

func (s *SessionDataSet) GetTimestamp() int64 {
	return s.ioTDBRpcDataSet.GetTimestamp()
}

func (s *SessionDataSet) GetValue(columnName string) interface{} {
	return s.ioTDBRpcDataSet.getValue(columnName)
}

func (s *SessionDataSet) GetRowRecord() (*RowRecord, error) {
	return s.ioTDBRpcDataSet.getRowRecord()
}

func (s *SessionDataSet) GetColumnCount() int {
	return s.ioTDBRpcDataSet.columnCount
}

func (s *SessionDataSet) GetColumnDataType(columnIndex int) TSDataType {
	return s.ioTDBRpcDataSet.columnTypeList[columnIndex]
}

func (s *SessionDataSet) GetColumnName(columnIndex int) string {
	return s.ioTDBRpcDataSet.columnNameList[columnIndex]
}

func (s *SessionDataSet) GetColumnNames() []string {
	return s.ioTDBRpcDataSet.columnNameList
}

func (s *SessionDataSet) IsIgnoreTimeStamp() bool {
	return s.ioTDBRpcDataSet.ignoreTimeStamp
}

func (s *SessionDataSet) IsClosed() bool {
	return s.ioTDBRpcDataSet.IsClosed()
}

func (s *SessionDataSet) Close() error {
	return s.ioTDBRpcDataSet.Close()
}

func NewSessionDataSet(sql string, columnNameList []string, columnTypeList []string,
	columnNameIndex map[string]int32,
	queryId int64, client *rpc.TSIServiceClient, sessionId int64, queryDataSet *rpc.TSQueryDataSet,
	ignoreTimeStamp bool, fetchSize int32, timeoutMs *int64) *SessionDataSet {

	return &SessionDataSet{
		ioTDBRpcDataSet: NewIoTDBRpcDataSet(sql, columnNameList, columnTypeList,
			columnNameIndex,
			queryId, client, sessionId, queryDataSet,
			ignoreTimeStamp, fetchSize, timeoutMs),
	}
}
