/*
 * Copyright 2015-present 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.vtnrsc;

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

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

import com.google.common.collect.ImmutableList;

/**
 * Implementation of port pair group.
 */
public final class DefaultPortPairGroup implements PortPairGroup {

    private final PortPairGroupId portPairGroupId;
    private final TenantId tenantId;
    private final String name;
    private final String description;
    private final List<PortPairId> portPairList;
    private final Map<PortPairId, Integer> portPairLoadMap;

    /**
     * Default constructor to create Port Pair Group.
     *
     * @param portPairGroupId port pair group id
     * @param tenantId tenant id
     * @param name name of port pair group
     * @param description description of port pair group
     * @param portPairList list of port pairs
     */
    private DefaultPortPairGroup(PortPairGroupId portPairGroupId, TenantId tenantId,
                                 String name, String description,
                                 List<PortPairId> portPairList) {

        this.portPairGroupId = portPairGroupId;
        this.tenantId = tenantId;
        this.name = name;
        this.description = description;
        this.portPairList = portPairList;
        portPairLoadMap = new ConcurrentHashMap<>();
        for (PortPairId portPairId : portPairList) {
            portPairLoadMap.put(portPairId, new Integer(0));
        }
    }

    @Override
    public PortPairGroupId portPairGroupId() {
        return portPairGroupId;
    }

    @Override
    public TenantId tenantId() {
        return tenantId;
    }

    @Override
    public String name() {
        return name;
    }

    @Override
    public String description() {
        return description;
    }

    @Override
    public List<PortPairId> portPairs() {
        return ImmutableList.copyOf(portPairList);
    }

    @Override
    public void addLoad(PortPairId portPairId) {
        int load = portPairLoadMap.get(portPairId);
        load = load + 1;
        portPairLoadMap.put(portPairId, new Integer(load));
    }

    @Override
    public int getLoad(PortPairId portPairId) {
        return portPairLoadMap.get(portPairId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(portPairGroupId, tenantId, name, description,
                            portPairList);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof DefaultPortPairGroup) {
            DefaultPortPairGroup that = (DefaultPortPairGroup) obj;
            return Objects.equals(portPairGroupId, that.portPairGroupId) &&
                    Objects.equals(tenantId, that.tenantId) &&
                    Objects.equals(name, that.name) &&
                    Objects.equals(description, that.description) &&
                    Objects.equals(portPairList, that.portPairList);
        }
        return false;
    }

    @Override
    public boolean exactMatch(PortPairGroup portPairGroup) {
        return this.equals(portPairGroup) &&
                Objects.equals(this.portPairGroupId, portPairGroup.portPairGroupId()) &&
                Objects.equals(this.tenantId, portPairGroup.tenantId());
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("id", portPairGroupId.toString())
                .add("tenantId", tenantId.toString())
                .add("name", name)
                .add("description", description)
                .add("portPairGroupList", portPairList)
                .toString();
    }

    /**
     * To create an instance of the builder.
     *
     * @return instance of builder
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * Builder class for Port pair group.
     */
    public static final class Builder implements PortPairGroup.Builder {

        private PortPairGroupId portPairGroupId;
        private TenantId tenantId;
        private String name;
        private String description;
        private List<PortPairId> portPairList;

        @Override
        public Builder setId(PortPairGroupId portPairGroupId) {
            this.portPairGroupId = portPairGroupId;
            return this;
        }

        @Override
        public Builder setTenantId(TenantId tenantId) {
            this.tenantId = tenantId;
            return this;
        }

        @Override
        public Builder setName(String name) {
            this.name = name;
            return this;
        }

        @Override
        public Builder setDescription(String description) {
            this.description = description;
            return this;
        }

        @Override
        public Builder setPortPairs(List<PortPairId> portPairs) {
            this.portPairList = portPairs;
            return this;
        }

        @Override
        public PortPairGroup build() {

            checkNotNull(portPairGroupId, "Port pair group id cannot be null");
            checkNotNull(tenantId, "Tenant id cannot be null");
            checkNotNull(portPairList, "Port pairs cannot be null");

            return new DefaultPortPairGroup(portPairGroupId, tenantId, name, description,
                                            portPairList);
        }
    }
}
