/*
 * Copyright 2020-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.kubevirtnode.api;

import com.google.common.base.MoreObjects;
import org.apache.commons.lang.StringUtils;
import org.onlab.osgi.DefaultServiceDirectory;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

import static com.google.common.base.Preconditions.checkArgument;
import static org.onosproject.kubevirtnode.api.Constants.DEFAULT_CLUSTER_NAME;
import static org.onosproject.kubevirtnode.api.Constants.GENEVE;
import static org.onosproject.kubevirtnode.api.Constants.GRE;
import static org.onosproject.kubevirtnode.api.Constants.INTEGRATION_TO_PHYSICAL_PREFIX;
import static org.onosproject.kubevirtnode.api.Constants.STT;
import static org.onosproject.kubevirtnode.api.Constants.VXLAN;
import static org.onosproject.net.AnnotationKeys.PORT_NAME;

/**
 * Representation of a KubeVirt node.
 */
public class DefaultKubevirtNode implements KubevirtNode {

    private static final String NOT_NULL_MSG = "Node % cannot be null";
    private static final String OVSDB = "ovsdb:";
    private static final int PORT_NAME_MAX_LENGTH = 15;

    private final String clusterName;
    private final String hostname;
    private final Type type;
    private final DeviceId intgBridge;
    private final DeviceId tunBridge;
    private final IpAddress managementIp;
    private final IpAddress dataIp;
    private final KubevirtNodeState state;
    private final Collection<KubevirtPhyInterface> phyIntfs;
    private final String gatewayBridgeName;
    private final String elbBridgeName;
    private final IpAddress elbIp;
    private final IpAddress elbGwIp;
    private final MacAddress elbGwMac;

    /**
     * A default constructor of kubevirt node.
     *
     * @param clusterName       clusterName
     * @param hostname          hostname
     * @param type              node type
     * @param intgBridge        integration bridge
     * @param tunBridge         tunnel bridge
     * @param managementIp      management IP address
     * @param dataIp            data IP address
     * @param state             node state
     * @param phyIntfs          physical interfaces
     * @param gatewayBridgeName  gateway bridge name
     * @param elbBridgeName     elb bridge name
     * @param elbIp             elb IP address
     * @param elbGwIp           elb gw IP address
     * @param elbGwMac          elb gw MAC address
     */
    protected DefaultKubevirtNode(String clusterName, String hostname, Type type,
                                  DeviceId intgBridge, DeviceId tunBridge,
                                  IpAddress managementIp, IpAddress dataIp,
                                  KubevirtNodeState state,
                                  Collection<KubevirtPhyInterface> phyIntfs,
                                  String gatewayBridgeName, String elbBridgeName, IpAddress elbIp,
                                  IpAddress elbGwIp, MacAddress elbGwMac) {
        this.clusterName = clusterName;
        this.hostname = hostname;
        this.type = type;
        this.intgBridge = intgBridge;
        this.tunBridge = tunBridge;
        this.managementIp = managementIp;
        this.dataIp = dataIp;
        this.state = state;
        this.phyIntfs = phyIntfs;
        this.gatewayBridgeName = gatewayBridgeName;
        this.elbBridgeName = elbBridgeName;
        this.elbIp = elbIp;
        this.elbGwIp = elbGwIp;
        this.elbGwMac = elbGwMac;
    }

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

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

    @Override
    public Type type() {
        return type;
    }

    @Override
    public DeviceId ovsdb() {
        return DeviceId.deviceId(OVSDB + managementIp().toString());
    }

    @Override
    public DeviceId intgBridge() {
        return intgBridge;
    }

    @Override
    public DeviceId tunBridge() {
        return tunBridge;
    }

    @Override
    public IpAddress managementIp() {
        return managementIp;
    }

    @Override
    public IpAddress dataIp() {
        return dataIp;
    }

    @Override
    public KubevirtNodeState state() {
        return state;
    }

    @Override
    public KubevirtNode updateState(KubevirtNodeState newState) {
        return new Builder()
                .hostname(hostname)
                .clusterName(clusterName)
                .type(type)
                .intgBridge(intgBridge)
                .tunBridge(tunBridge)
                .managementIp(managementIp)
                .dataIp(dataIp)
                .state(newState)
                .phyIntfs(phyIntfs)
                .gatewayBridgeName(gatewayBridgeName)
                .elbBridgeName(elbBridgeName)
                .elbIp(elbIp)
                .elbGwIp(elbGwIp)
                .elbGwMac(elbGwMac)
                .build();
    }

    @Override
    public KubevirtNode updateIntgBridge(DeviceId deviceId) {
        return new Builder()
                .hostname(hostname)
                .clusterName(clusterName)
                .type(type)
                .intgBridge(deviceId)
                .tunBridge(tunBridge)
                .managementIp(managementIp)
                .dataIp(dataIp)
                .state(state)
                .phyIntfs(phyIntfs)
                .gatewayBridgeName(gatewayBridgeName)
                .elbBridgeName(elbBridgeName)
                .elbIp(elbIp)
                .elbGwIp(elbGwIp)
                .elbGwMac(elbGwMac)
                .build();
    }

    @Override
    public KubevirtNode updateTunBridge(DeviceId deviceId) {
        return new Builder()
                .hostname(hostname)
                .clusterName(clusterName)
                .type(type)
                .intgBridge(intgBridge)
                .tunBridge(deviceId)
                .managementIp(managementIp)
                .dataIp(dataIp)
                .state(state)
                .phyIntfs(phyIntfs)
                .gatewayBridgeName(gatewayBridgeName)
                .elbBridgeName(elbBridgeName)
                .elbIp(elbIp)
                .elbGwIp(elbGwIp)
                .elbGwMac(elbGwMac)
                .build();
    }

    @Override
    public Collection<KubevirtPhyInterface> phyIntfs() {
        if (phyIntfs == null) {
            return new ArrayList<>();
        }

        return phyIntfs;
    }

    @Override
    public Set<PortNumber> physPatchPorts() {
        Set<PortNumber> portNumbers = new HashSet<>();
        for (KubevirtPhyInterface phyIntf : this.phyIntfs()) {
            String portName = structurePortName(
                    INTEGRATION_TO_PHYSICAL_PREFIX + phyIntf.network());
            PortNumber portNumber = patchPort(portName);
            if (portNumber != null) {
                portNumbers.add(portNumber);
            }
        }
        return portNumbers;
    }

    @Override
    public PortNumber vxlanPort() {
        return tunnelPort(VXLAN);
    }

    @Override
    public PortNumber grePort() {
        return tunnelPort(GRE);
    }

    @Override
    public PortNumber genevePort() {
        return tunnelPort(GENEVE);
    }

    @Override
    public PortNumber sttPort() {
        return tunnelPort(STT);
    }

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

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

    @Override
    public IpAddress elbIp() {
        return elbIp;
    }

    @Override
    public IpAddress elbGwIp() {
        return elbGwIp;
    }

    @Override
    public MacAddress elbGwMac() {
        return elbGwMac;
    }

    private PortNumber tunnelPort(String tunnelType) {
        if (dataIp == null) {
            return null;
        }
        DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
        Port port = deviceService.getPorts(tunBridge).stream()
                .filter(p -> p.isEnabled() &&
                        Objects.equals(p.annotations().value(PORT_NAME), tunnelType))
                .findAny().orElse(null);
        return port != null ? port.number() : null;
    }

    private PortNumber patchPort(String portName) {
        DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
        Port port = deviceService.getPorts(intgBridge).stream()
                .filter(p -> p.isEnabled() &&
                        Objects.equals(p.annotations().value(PORT_NAME), portName))
                .findAny().orElse(null);
        return port != null ? port.number() : null;
    }

    /**
     * Re-structures the OVS port name.
     * The length of OVS port name should be not large than 15.
     *
     * @param portName  original port name
     * @return re-structured OVS port name
     */
    private String structurePortName(String portName) {

        // The size of OVS port name should not be larger than 15
        if (portName.length() > PORT_NAME_MAX_LENGTH) {
            return StringUtils.substring(portName, 0, PORT_NAME_MAX_LENGTH);
        }

        return portName;
    }

    /**
     * Returns new builder instance.
     *
     * @return kubevirt node builder
     */
    public static Builder builder() {
        return new Builder();
    }

    /**
     * Returns new builder instance with the given node as a default value.
     *
     * @param node kubevirt node
     * @return kubevirt node builder
     */
    public static Builder from(KubevirtNode node) {
        return new Builder()
                .hostname(node.hostname())
                .clusterName(node.clusterName())
                .type(node.type())
                .intgBridge(node.intgBridge())
                .tunBridge(node.tunBridge())
                .managementIp(node.managementIp())
                .dataIp(node.dataIp())
                .state(node.state())
                .phyIntfs(node.phyIntfs())
                .gatewayBridgeName(node.gatewayBridgeName())
                .elbBridgeName(node.elbBridgeName())
                .elbIp(node.elbIp())
                .elbGwIp(node.elbGwIp())
                .elbGwMac(node.elbGwMac());
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        DefaultKubevirtNode that = (DefaultKubevirtNode) o;
        return clusterName.equals(that.clusterName) &&
                hostname.equals(that.hostname) &&
                type == that.type &&
                intgBridge.equals(that.intgBridge) &&
                tunBridge.equals(that.tunBridge) &&
                managementIp.equals(that.managementIp) &&
                dataIp.equals(that.dataIp);
    }

    @Override
    public int hashCode() {
        return Objects.hash(clusterName, hostname, type, intgBridge, tunBridge,
                managementIp, dataIp);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                .add("clusterName", clusterName)
                .add("hostname", hostname)
                .add("type", type)
                .add("intgBridge", intgBridge)
                .add("tunBridge", tunBridge)
                .add("managementIp", managementIp)
                .add("dataIp", dataIp)
                .add("state", state)
                .add("phyIntfs", phyIntfs)
                .add("gatewayBridgeName", gatewayBridgeName)
                .add("elbBridgeName", elbBridgeName)
                .add("elbIp", elbIp)
                .add("elbGwIp", elbGwIp)
                .add("elbGwMac", elbGwMac)
                .toString();
    }

    public static final class Builder implements KubevirtNode.Builder {

        private String clusterName;
        private String hostname;
        private Type type;
        private DeviceId intgBridge;
        private DeviceId tunBridge;
        private IpAddress managementIp;
        private IpAddress dataIp;
        private KubevirtNodeState state;
        private Collection<KubevirtPhyInterface> phyIntfs;
        private String gatewayBridgeName;
        private String elbBridgeName;
        private IpAddress elbIp;
        private IpAddress elbGwIp;
        private MacAddress elbGwMac;

        // private constructor not intended to use from external
        private Builder() {
        }

        @Override
        public KubevirtNode build() {
            checkArgument(hostname != null, NOT_NULL_MSG, "hostname");
            checkArgument(type != null, NOT_NULL_MSG, "type");
            checkArgument(state != null, NOT_NULL_MSG, "state");
            checkArgument(managementIp != null, NOT_NULL_MSG, "management IP");

            if (StringUtils.isEmpty(clusterName)) {
                clusterName = DEFAULT_CLUSTER_NAME;
            }

            return new DefaultKubevirtNode(
                    clusterName,
                    hostname,
                    type,
                    intgBridge,
                    tunBridge,
                    managementIp,
                    dataIp,
                    state,
                    phyIntfs,
                    gatewayBridgeName,
                    elbBridgeName,
                    elbIp,
                    elbGwIp,
                    elbGwMac
            );
        }

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

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

        @Override
        public Builder type(Type type) {
            this.type = type;
            return this;
        }

        @Override
        public Builder intgBridge(DeviceId deviceId) {
            this.intgBridge = deviceId;
            return this;
        }

        @Override
        public Builder tunBridge(DeviceId deviceId) {
            this.tunBridge = deviceId;
            return this;
        }

        @Override
        public Builder managementIp(IpAddress managementIp) {
            this.managementIp = managementIp;
            return this;
        }

        @Override
        public Builder dataIp(IpAddress dataIp) {
            this.dataIp = dataIp;
            return this;
        }

        @Override
        public Builder phyIntfs(Collection<KubevirtPhyInterface> phyIntfs) {
            this.phyIntfs = phyIntfs;
            return this;
        }

        @Override
        public Builder state(KubevirtNodeState state) {
            this.state = state;
            return this;
        }

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

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

        @Override
        public Builder elbIp(IpAddress elbIp) {
            this.elbIp = elbIp;
            return this;
        }

        @Override
        public Builder elbGwIp(IpAddress elbGwIp) {
            this.elbGwIp = elbGwIp;
            return this;
        }

        @Override
        public Builder elbGwMac(MacAddress elbGwMac) {
            this.elbGwMac = elbGwMac;
            return this;
        }
    }
}
