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

#include <string>

#include "common/constant/tsfile_constant.h"
#include "common/device_id.h"
#ifdef ENABLE_ANTLR4
#include "parser/generated/PathParser.h"
#include "parser/path_nodes_generator.h"
#endif
#include "utils/errno_define.h"

namespace storage {

struct Path {
    std::string measurement_;
    std::shared_ptr<IDeviceID> device_id_;
    std::string full_path_;

    Path() {}

    Path(std::string& device, std::string& measurement)
        : measurement_(measurement),
          device_id_(std::make_shared<StringArrayDeviceID>(device)) {
        full_path_ = device + "." + measurement;
    }

    Path(const std::string& path_sc, bool if_split = true) {
        if (!path_sc.empty()) {
            if (!if_split) {
                full_path_ = path_sc;
                device_id_ = std::make_shared<StringArrayDeviceID>(path_sc);
            } else {
#ifdef ENABLE_ANTLR4
                std::vector<std::string> nodes =
                    PathNodesGenerator::invokeParser(path_sc);
#else
                std::vector<std::string> nodes =
                    IDeviceID::split_string(path_sc, '.');
#endif
                if (nodes.size() > 1) {
                    // Join nodes, then parse like write path / Java Path
                    // (route through the interpretive string ctor instead of
                    // the literal per-segment vector ctor, so a stored
                    // "root.sg.d1" device matches a query path
                    // "root.sg.d1.s1").
                    std::string device_joined;
                    for (size_t i = 0; i + 1 < nodes.size(); ++i) {
                        if (i > 0) {
                            device_joined += PATH_SEPARATOR_CHAR;
                        }
                        device_joined += nodes[i];
                    }
                    device_id_ =
                        std::make_shared<StringArrayDeviceID>(device_joined);
                    measurement_ = nodes[nodes.size() - 1];
                    full_path_ =
                        device_id_->get_device_name() + "." + measurement_;
                } else {
                    // Single-node path (no separator): there is no device
                    // prefix, so the lone token is the measurement and the
                    // device id is left empty.
                    full_path_ = path_sc;
                    device_id_ = std::make_shared<StringArrayDeviceID>();
                    measurement_ = path_sc;
                }
            }
        } else {
            full_path_ = "";
            device_id_ = std::make_shared<StringArrayDeviceID>();
            measurement_ = "";
        }
    }

    bool operator==(const Path& path) {
        if (measurement_.compare(path.measurement_) == 0 &&
            device_id_->get_device_name().compare(
                path.device_id_->get_device_name()) == 0) {
            return true;
        } else {
            return false;
        }
    }
};

}  // namespace storage

#endif  // COMMON_READ_COMMON_PATH_H
