/*
 * Copyright 2014 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.intent.constraint;

import com.google.common.collect.ImmutableSet;
import org.onosproject.net.Link;
import org.onosproject.net.resource.link.LinkResourceService;

import java.util.Objects;
import java.util.Set;

import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Constraint that evaluates links based on their type.
 */
public class LinkTypeConstraint extends BooleanConstraint {

    private final Set<Link.Type> types;
    private final boolean isInclusive;

    /**
     * Creates a new constraint for requesting connectivity using or avoiding
     * the specified link types.
     *
     * @param inclusive indicates whether the given link types are to be
     *                  permitted or avoided
     * @param types     link types
     */
    public LinkTypeConstraint(boolean inclusive, Link.Type... types) {
        checkNotNull(types, "Link types cannot be null");
        checkArgument(types.length > 0, "There must be more than one type");
        this.types = ImmutableSet.copyOf(types);
        this.isInclusive = inclusive;
    }

    // Constructor for serialization
    private LinkTypeConstraint() {
        this.types = null;
        this.isInclusive = false;
    }

    @Override
    public boolean isValid(Link link, LinkResourceService resourceService) {
        boolean contains = types.contains(link.type());
        return isInclusive ? contains : !contains;
    }

    /**
     * Returns the set of link types.
     *
     * @return set of link types
     */
    public Set<Link.Type> types() {
        return types;
    }

    /**
     * Indicates if the constraint is inclusive or exclusive.
     *
     * @return true if inclusive
     */
    public boolean isInclusive() {
        return isInclusive;
    }

    @Override
    public int hashCode() {
        return Objects.hash(types, isInclusive);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        final LinkTypeConstraint other = (LinkTypeConstraint) obj;
        return Objects.equals(this.types, other.types) && Objects.equals(this.isInclusive, other.isInclusive);
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("inclusive", isInclusive)
                .add("types", types)
                .toString();
    }
}
