/*
 * Copyright 2016-present Open Networking Foundation
 *
 * 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.ovsdb.controller;

import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.ovsdb.controller.OvsdbConstant.*;

import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import com.google.common.collect.Maps;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.behaviour.PatchDescription;
import org.onosproject.net.behaviour.TunnelDescription;

/**
 * The class representing an OVSDB interface.
 * This class is immutable.
 */
public final class OvsdbInterface {

    public enum Type {
        /**
         * An ordinary network device, e.g. eth0 on Linux.
         */
        SYSTEM,
        /**
         * A simulated network device that sends and receives traffic.
         */
        INTERNAL,
        /**
         * A TUN/TAP device managed by Open vSwitch.
         */
        TAP,
        /**
         * An Ethernet over RFC 2890 Generic Routing Encapsulation over IPv4 IPsec tunnel.
         */
        GRE,
        /**
         * An Ethernet tunnel over the experimental, UDP-based VXLAN protocol.
         */
        VXLAN,
        /**
         * A pair of virtual devices that act as a patch cable.
         */
        PATCH,
        /**
         * A DPDK net device.
         */
        DPDK
    }

    private final String name;
    private final Type type;
    private final Optional<Long> mtu;

    /* Adds more configs */

    /* Fields start with "options:" prefix defined in the OVSDB */
    private final Map<String, String> options;

    private OvsdbInterface(String name, Type type, Optional<Long> mtu, Map<String, String> options) {
        this.name = name;
        this.type = checkNotNull(type, "the type of interface can not be null");
        this.mtu = mtu;
        this.options = Maps.newHashMap(options);
    }

    /**
     * Returns name of the interface.
     *
     * @return interface name
     */
    public String name() {
        return name;
    }

    /**
     * Returns type of the interface.
     *
     * @return interface type
     */
    public Type type() {
        return type;
    }

    /**
     * Returns type of the interface with lowercase string.
     *
     * @return interface type string
     */
    public String typeToString() {
        return type.name().toLowerCase();
    }

    /**
     * Returns mtu of the interface.
     *
     * @return interface mtu
     */
    public Optional<Long> mtu() {
        return mtu;
    }

    /**
     * Returns optional configs of the interface.
     *
     * @return interface options
     */
    public Map<String, String> options() {
        return options;
    }

    @Override
    public int hashCode() {
        return Objects.hash(name);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof OvsdbInterface) {
            final OvsdbInterface otherOvsdbInterface = (OvsdbInterface) obj;
            return Objects.equals(this.name, otherOvsdbInterface.name);
        }
        return false;
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("name", name)
                .add("type", type)
                .add("mtu", mtu)
                .add("options", options)
                .toString();
    }

    /**
     * Returns new OVSDB interface builder.
     *
     * @return ovsdb interface builder
     */
    public static OvsdbInterface.Builder builder() {
        return new Builder();
    }

    /**
     * Returns new OVSDB interface builder with tunnel interface description.
     *
     * @param tunnelDesc tunnel interface description
     * @return ovsdb interface builder
     */
    public static OvsdbInterface.Builder builder(TunnelDescription tunnelDesc) {
        return new Builder(tunnelDesc);
    }

    /**
     * Returns new OVSDB interface builder with patch interface description.
     *
     * @param patchDesc patch interface description
     * @return ovsdb interface builder
     */
    public static OvsdbInterface.Builder builder(PatchDescription patchDesc) {
        return new Builder(patchDesc);
    }

    /**
     * Builder of OVSDB interface entities.
     */
    public static final class Builder {
        private String name;
        private Type type;
        private Optional<Long> mtu = Optional.empty();
        private Map<String, String> options = Maps.newHashMap();

        private Builder() {
        }

        /**
         * Constructs a builder with a given tunnel interface description.
         *
         * @param tunnelDesc tunnel interface description
         */
        private Builder(TunnelDescription tunnelDesc) {
            this.name = tunnelDesc.ifaceName();
            this.type = Type.valueOf(tunnelDesc.type().name());

            Map<String, String> tunOptions = Maps.newHashMap();
            if (tunnelDesc.local().isPresent()) {
                tunOptions.put(TUNNEL_LOCAL_IP, tunnelDesc.local().get().strValue());
            }
            if (tunnelDesc.remote().isPresent()) {
                tunOptions.put(TUNNEL_REMOTE_IP, tunnelDesc.remote().get().strValue());
            }
            if (tunnelDesc.key().isPresent()) {
                tunOptions.put(TUNNEL_KEY, tunnelDesc.key().get().strValue());
            }

            // set other configurations if there are any
            tunOptions.putAll(((DefaultAnnotations) tunnelDesc.annotations()).asMap());
            options = tunOptions;
        }

        /**
         * Constructs a builder with a given patch interface description.
         *
         * @param patchDesc patch interface description
         */
        private Builder(PatchDescription patchDesc) {
            this.name = patchDesc.ifaceName();
            this.type = Type.PATCH;

            Map<String, String> patchOptions = Maps.newHashMap();
            patchOptions.put(PATCH_PEER, patchDesc.peer());
            options = patchOptions;
        }

        /**
         * Returns new OVSDB interface.
         *
         * @return ovsdb interface
         */
        public OvsdbInterface build() {
            return new OvsdbInterface(name, type, mtu, options);
        }

        /**
         * Returns OVSDB interface builder with a given name.
         *
         * @param name name of the interface
         * @return ovsdb interface builder
         */
        public Builder name(String name) {
            this.name = name;
            return this;
        }

        /**
         * Returns OVSDB interface builder with a given interface type.
         *
         * @param type type of the interface
         * @return ovsdb interface builder
         */
        public Builder type(Type type) {
            this.type = type;
            return this;
        }

        /**
         * Returns OVSDB interface builder with a given interface mtu.
         *
         * @param mtu mtu of the interface
         * @return ovsdb interface builder
         */
        public Builder mtu(Long mtu) {
            this.mtu = Optional.ofNullable(mtu);
            return this;
        }

        /**
         * Returns OVSDB interface builder with given options.
         *
         * @param options map of options
         * @return ovsdb interface builder
         */
        public Builder options(Map<String, String> options) {
            this.options = Maps.newHashMap(options);
            return this;
        }
    }
}
