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

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

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

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
    }

    private final String name;
    private final Type type;

    /* Adds more configs */

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

    private OvsdbInterface(String name, Type type, Map<String, String> options) {
        this.name = name;
        this.type = type;
        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 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("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 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, 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 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;
        }
    }
}
