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

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

import java.util.Collection;
import java.util.Objects;

/**
 * Representation of a Router gateway.
 */
public final class RouterGateway {

    private final TenantNetworkId networkId;
    private final boolean enableSnat;
    private final Collection<FixedIp> externalFixedIps;

    // Public construction is prohibited
    private RouterGateway(TenantNetworkId networkId, boolean enableSnat,
                         Collection<FixedIp> externalFixedIps) {
        this.networkId = checkNotNull(networkId, "networkId cannot be null");
        this.enableSnat = checkNotNull(enableSnat, "enableSnat cannot be null");
        this.externalFixedIps = checkNotNull(externalFixedIps, "externalFixedIps cannot be null");
    }

    /**
     * Creates router gateway object.
     *
     * @param networkId network identifier
     * @param enableSnat SNAT enable or not
     * @param externalFixedIps external fixed IP
     * @return RouterGateway
     */
    public static RouterGateway routerGateway(TenantNetworkId networkId, boolean enableSnat,
                                              Collection<FixedIp> externalFixedIps) {
        return new RouterGateway(networkId, enableSnat, externalFixedIps);
    }

    /**
     * Returns network identifier.
     *
     * @return networkId
     */
    public TenantNetworkId networkId() {
        return networkId;
    }

    /**
     * Return SNAT enable or not.
     *
     * @return enableSnat
     */
    public boolean enableSnat() {
        return enableSnat;
    }

    /**
     * Return external fixed Ip.
     *
     * @return externalFixedIps
     */
    public Collection<FixedIp> externalFixedIps() {
        return externalFixedIps;
    }

    @Override
    public int hashCode() {
        return Objects.hash(networkId, enableSnat, externalFixedIps);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof RouterGateway) {
            final RouterGateway that = (RouterGateway) obj;
            return Objects.equals(this.networkId, that.networkId)
                    && Objects.equals(this.enableSnat, that.enableSnat)
                    && Objects.equals(this.externalFixedIps, that.externalFixedIps);
        }
        return false;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("networkId", networkId)
                .add("enableSnat", enableSnat)
                .add("externalFixedIps", externalFixedIps)
                .toString();
    }
}
