/*
 * 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.grouphandler;

import java.util.List;

import org.onosproject.net.group.GroupKey;

/**
 * Representation of policy based group identifiers.
 * Opaque to group handler applications and only the outermost
 * policy group identifier in a chain is visible to the applications.
 */
public class PolicyGroupIdentifier implements GroupKey {
    private String id;
    private List<PolicyGroupParams> inputParams;
    private List<GroupBucketIdentifier> bucketIds;

    /**
     * Constructor.
     *
     * @param id unique identifier associated with the policy group
     * @param input policy group params associated with this group
     * @param bucketIds buckets associated with this group
     */
    protected PolicyGroupIdentifier(String id,
                                 List<PolicyGroupParams> input,
                                 List<GroupBucketIdentifier> bucketIds) {
        this.id = id;
        this.inputParams = input;
        this.bucketIds = bucketIds;
    }

    /**
     * Returns the bucket identifier list associated with the policy
     * group identifier.
     *
     * @return list of bucket identifier
     */
    protected List<GroupBucketIdentifier> bucketIds() {
        return this.bucketIds;
    }

    @Override
    public int hashCode() {
        int result = 17;
        int combinedHash = 0;
        for (PolicyGroupParams input:inputParams) {
            combinedHash = combinedHash + input.hashCode();
        }
        for (GroupBucketIdentifier bucketId:bucketIds) {
            combinedHash = combinedHash + bucketId.hashCode();
        }
        result = 31 * result + combinedHash;

        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (obj instanceof PolicyGroupIdentifier) {
            PolicyGroupIdentifier that = (PolicyGroupIdentifier) obj;
            boolean result = this.id.equals(that.id);
            result = result &&
                    this.inputParams.containsAll(that.inputParams) &&
                    that.inputParams.containsAll(this.inputParams);
            result = result &&
                    this.bucketIds.containsAll(that.bucketIds) &&
                    that.bucketIds.containsAll(this.bucketIds);
            return result;
        }

        return false;
    }
}
