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

import java.util.List;

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