/*
 * 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.annotations.Beta;
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.
 */
@Beta
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;
    }

    /**
     * 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();
    }
}
