/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed 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 org.onosproject.net.newresource;

import com.google.common.annotations.Beta;
import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;

import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

/**
 * An object that is used to locate a resource in a network.
 * A ResourcePath represents a path that is hierarchical and composed of a sequence
 * of elementary resources that are not globally identifiable. A ResourcePath can be a globally
 * unique resource identifier.
 *
 * Two types of resource are considered. One is discrete type and the other is continuous type.
 * Discrete type resource is a resource whose amount is measured as a discrete unit. VLAN ID and
 * MPLS label are examples of discrete type resource. Continuous type resource is a resource whose
 * amount is measured as a continuous value. Bandwidth is an example of continuous type resource.
 * A double value is associated with a continuous type value.
 *
 * Users of this class must keep the semantics of resources regarding the hierarchical structure.
 * For example, resource path, Link:1/VLAN ID:100, is valid, but resource path, VLAN ID:100/Link:1
 * is not valid because a link is not a sub-component of a VLAN ID.
 */
@Beta
public abstract class ResourcePath {

    private final Discrete parent;
    private final Object last;

    public static final Discrete ROOT = new Discrete();

    /**
     * Creates an resource path which represents a discrete-type resource from the specified components.
     *
     * @param components components of the path. The order represents hierarchical structure of the resource.
     */
    public static ResourcePath discrete(Object... components) {
        if (components.length == 0) {
            return ROOT;
        } else {
            return new Discrete(ImmutableList.copyOf(components));
        }
    }

    /**
     * Creates an resource path which represents a continuous-type resource from the specified components.
     *
     * @param value amount of the resource
     * @param components components of the path. The order represents hierarchical structure of the resource.
     */
    public static ResourcePath continuous(double value, Object... components) {
        return new Continuous(ImmutableList.copyOf(components), value);
    }

    /**
     * Creates an resource path from the specified components.
     *
     * @param components components of the path. The order represents hierarchical structure of the resource.
     */
    ResourcePath(List<Object> components) {
        checkNotNull(components);
        checkArgument(!components.isEmpty());

        LinkedList<Object> children = new LinkedList<>(components);
        this.last = children.pollLast();
        if (children.isEmpty()) {
            this.parent = ROOT;
        } else {
            this.parent = new Discrete(children);
        }
    }

    /**
     * Creates an resource path from the specified parent and child.
     *
     * @param parent the parent of this resource
     * @param last a child of the parent
     */
    ResourcePath(Discrete parent, Object last) {
        checkNotNull(parent);
        checkNotNull(last);

        this.parent = parent;
        this.last = last;
    }

    // for serialization
    private ResourcePath() {
        this.parent = null;
        this.last = null;
    }

    /**
     * Returns the components of this resource path.
     *
     * @return the components of this resource path
     */
    public List<Object> components() {
        LinkedList<Object> components = new LinkedList<>();

        ResourcePath current = this;
        while (current.parent().isPresent()) {
            components.addFirst(current.last);
            current = current.parent;
        }

        return components;
    }

    /**
     * Returns the parent resource path of this instance.
     * E.g. if this path is Link:1/VLAN ID:100, the return value is the resource path for Link:1.
     *
     * @return the parent resource path of this instance.
     * If there is no parent, empty instance will be returned.
     */
    public Optional<Discrete> parent() {
        return Optional.ofNullable(parent);
    }

    public ResourcePath child(Object child) {
        checkState(this instanceof Discrete);

        return new Discrete((Discrete) this, child);
    }

    public ResourcePath child(Object child, double value) {
        checkState(this instanceof Discrete);

        return new Continuous((Discrete) this, child, value);
    }

    /**
     * Returns the last component of this instance.
     *
     * @return the last component of this instance.
     * The return value is equal to the last object of {@code components()}.
     */
    public Object last() {
        return last;
    }

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

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof ResourcePath)) {
            return false;
        }
        final ResourcePath that = (ResourcePath) obj;
        return Objects.equals(this.parent, that.parent)
                && Objects.equals(this.last, that.last);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                .add("parent", parent)
                .add("last", last)
                .toString();
    }

    /**
     * Represents a resource path which specifies a resource which can be measured
     * as a discrete unit. A VLAN ID and a MPLS label of a link are examples of the resource.
     * <p>
     * Note: This class is exposed to the public, but intended to be used in the resource API
     * implementation only. It is not for resource API user.
     * </p>
     */
    public static final class Discrete extends ResourcePath {
        private Discrete() {
            super();
        }

        private Discrete(List<Object> components) {
            super(components);
        }

        private Discrete(Discrete parent, Object last) {
            super(parent, last);
        }
    }

    /**
     * Represents a resource path which specifies a resource which can be measured
     * as continuous value. Bandwidth of a link is an example of the resource.
     * <p>
     * Note: This class is exposed to the public, but intended to be used in the resource API
     * implementation only. It is not for resource API user.
     */
    public static final class Continuous extends ResourcePath {
        // Note: value is not taken into account for equality
        private final double value;

        private Continuous(List<Object> components, double value) {
            super(components);
            this.value = value;
        }

        public Continuous(Discrete parent, Object last, double value) {
            super(parent, last);
            this.value = value;
        }

        /**
         * Returns the value of the resource amount.
         *
         * @return the value of the resource amount
         */
        public double value() {
            return value;
        }
    }
}
