/*
 * Copyright (c) 2019 the Eclipse Milo Authors
 *
 * This program and the accompanying materials are made
 * available under the terms of the Eclipse Public License 2.0
 * which is available at https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 */

package org.eclipse.milo.opcua.sdk.server.nodes.factories;

import java.util.Objects;

import org.eclipse.milo.opcua.stack.core.types.builtin.QualifiedName;

public class BrowsePath {

    static final BrowsePath ROOT = new BrowsePath(
        null,
        new QualifiedName(0, "/")
    );

    final BrowsePath parent;
    final QualifiedName browseName;

    BrowsePath(BrowsePath parent, QualifiedName browseName) {
        this.parent = parent;
        this.browseName = browseName;
    }

    /**
     * Joins the components of this browse path with "/" as the separator.
     *
     * @return a String with the components of this browse path joined with "/" as the separator.
     */
    public String join() {
        return join("/", true);
    }

    /**
     * Join the components of this browse path with {@code separator}.
     *
     * @param separator             the separator to join with.
     * @param includeNamespaceIndex include the namespace index of each browse name component.
     * @return a String with the components of this browse path joined by {@code separator}.
     */
    public String join(String separator, boolean includeNamespaceIndex) {
        if (parent == null) {
            return "";
        } else {
            String s = parent.join(separator, includeNamespaceIndex);
            if (!s.endsWith(separator)) {
                s += separator;
            }
            if (includeNamespaceIndex) {
                s += browseName.getNamespaceIndex() + ":";
            }
            return s + browseName.getName();
        }
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        BrowsePath that = (BrowsePath) o;
        return Objects.equals(parent, that.parent) &&
            Objects.equals(browseName, that.browseName);
    }

    @Override
    public int hashCode() {
        return Objects.hash(parent, browseName);
    }

    @Override
    public String toString() {
        return join();
    }

}
