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

#include <memory>
#include <string>
#include <vector>

#include "tsfile_reader.h"

namespace storage {

class TsFileTreeReader {
   public:
    TsFileTreeReader();
    ~TsFileTreeReader();

    /**
     * @brief open the tsfile
     *
     * @param file_path the path of the tsfile which will be opened
     * @return Returns 0 on success, or a non-zero error code on failure.
     */
    int open(const std::string& file_path);

    /**
     * @brief close the tsfile, this method should be called after the
     * query is finished
     *
     * @return Returns 0 on success, or a non-zero error code on failure.
     */
    int close();

    /**
     * @brief Query time series data for specified devices and measurements
     * within a time range
     *
     * @param device_ids List of device identifiers to query
     * @param measurement_names List of measurement names to query
     * @param start_time Start timestamp of the query range (inclusive)
     * @param end_time End timestamp of the query range (inclusive)
     * @param[out] result_set Pointer to the ResultSet that will contain query
     * results
     * @return Returns 0 on success, or a non-zero error code on failure.
     *         The caller is responsible for destroying the result set using
     * destroy_query_data_set()
     */
    int query(const std::vector<std::string>& device_ids,
              const std::vector<std::string>& measurement_names,
              int64_t start_time, int64_t end_time, ResultSet*& result_set);

    /**
     * @brief Query time series data by row with offset and limit.
     *
     * Merges multiple paths by time, skips the first @p offset rows,
     * and returns at most @p limit rows. When only a single path is
     * selected, chunk/page statistics are used to skip entire blocks
     * without decoding. Once @p limit rows have been returned, no
     * further data is loaded from storage.
     *
     * @param device_ids        List of device identifiers to query.
     * @param measurement_names List of measurement names to query.
     * @param offset            Number of leading rows to skip (>= 0).
     * @param limit             Maximum rows to return. < 0 means unlimited.
     * @param[out] result_set   The result set containing query results.
     * @return Returns 0 on success, or a non-zero error code on failure.
     *         The caller is responsible for destroying the result set using
     *         destroy_query_data_set().
     */
    int queryByRow(const std::vector<std::string>& device_ids,
                   const std::vector<std::string>& measurement_names,
                   int offset, int limit, ResultSet*& result_set);

    /**
     * @brief Destroy and deallocate the query result set
     *
     * @param result_set Pointer to the ResultSet to be destroyed
     * @note This method should be called after the result set is no longer
     * needed to prevent memory leaks
     */
    void destroy_query_data_set(ResultSet* result_set);

    /**
     * @brief Get the measurement schema for a specific device
     *
     * @param device_id The device identifier
     * @return Pointer to the MeasurementSchema for the device, or nullptr if
     * not found
     * @note The caller should not delete the returned pointer as it's managed
     * by the reader
     */
    std::vector<MeasurementSchema> get_device_schema(
        const std::string& device_id);

    /**
     * @brief Get all device identifiers in the TsFile (string form).
     *
     * @return Vector of device identifier strings
     */
    std::vector<std::string> get_all_device_ids();

    /**
     * @brief Get all devices in the file (IDeviceID form).
     *
     * @return Vector of IDeviceID for all devices
     */
    std::vector<std::shared_ptr<IDeviceID>> get_all_devices();

    /**
     * @brief Get timeseries metadata for specified devices.
     *
     * Only devices that exist in the file are included.
     *
     * @param device_ids device list to query
     * @return map: IDeviceID -> list of timeseries metadata (only existing)
     */
    DeviceTimeseriesMetadataMap get_timeseries_metadata(
        const std::vector<std::shared_ptr<IDeviceID>>& device_ids);

    /**
     * @brief Get timeseries metadata for all devices in the file.
     *
     * @return map: IDeviceID -> list of timeseries metadata
     */
    DeviceTimeseriesMetadataMap get_timeseries_metadata();

   private:
    std::shared_ptr<TsFileReader>
        tsfile_reader_;  ///< Underlying TsFile reader implementation
};

}  // namespace storage

#endif  // READER_TSFILE_TREE_READER_H