/*
 * Copyright 2019-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.k8snode.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.k8snode.api.K8sApiConfig.Mode;
import org.onosproject.net.Annotations;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.net.device.DeviceService;

import java.util.Objects;
import java.util.UUID;

import static com.google.common.base.Preconditions.checkArgument;
import static org.onosproject.k8snode.api.Constants.DEFAULT_CLUSTER_NAME;
import static org.onosproject.k8snode.api.Constants.EXTERNAL_BRIDGE;
import static org.onosproject.k8snode.api.Constants.GENEVE_TUNNEL;
import static org.onosproject.k8snode.api.Constants.GRE_TUNNEL;
import static org.onosproject.k8snode.api.Constants.INTEGRATION_BRIDGE;
import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_EXTERNAL_BRIDGE;
import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_LOCAL_BRIDGE;
import static org.onosproject.k8snode.api.Constants.INTEGRATION_TO_TUN_BRIDGE;
import static org.onosproject.k8snode.api.Constants.LOCAL_BRIDGE;
import static org.onosproject.k8snode.api.Constants.LOCAL_TO_INTEGRATION_BRIDGE;
import static org.onosproject.k8snode.api.Constants.PHYSICAL_EXTERNAL_BRIDGE;
import static org.onosproject.k8snode.api.Constants.TUNNEL_BRIDGE;
import static org.onosproject.k8snode.api.Constants.TUN_TO_INTEGRATION_BRIDGE;
import static org.onosproject.k8snode.api.Constants.VXLAN_TUNNEL;
import static org.onosproject.k8snode.api.K8sApiConfig.Mode.NORMAL;
import static org.onosproject.k8snode.api.K8sApiConfig.Mode.PASSTHROUGH;
import static org.onosproject.net.AnnotationKeys.PORT_NAME;

/**
 * Representation of a kubernetes node.
 */
public class DefaultK8sNode implements K8sNode {

    private static final String PORT_MAC = "portMac";
    private static final String FLOW_KEY = "flow";

    private static final int SHORT_NAME_LENGTH = 10;

    private final String clusterName;
    private final String hostname;
    private final Type type;
    private final int segmentId;
    private final Mode mode;
    private final DeviceId intgBridge;
    private final DeviceId extBridge;
    private final DeviceId localBridge;
    private final DeviceId tunBridge;
    private final IpAddress managementIp;
    private final IpAddress dataIp;
    private final K8sNodeState state;
    private final String extIntf;
    private final K8sExternalNetwork extNetwork;
    private final String podCidr;

    private static final String NOT_NULL_MSG = "Node % cannot be null";

    private static final String OVSDB = "ovsdb:";

    /**
     * A default constructor of kubernetes Node.
     *
     * @param clusterName       clusterName
     * @param hostname          hostname
     * @param type              node type
     * @param segmentId         segment identifier
     * @param mode              CNI running mode
     * @param intgBridge        integration bridge
     * @param extBridge         external bridge
     * @param localBridge       local bridge
     * @param tunBridge         tunnel bridge
     * @param extIntf           external interface
     * @param managementIp      management IP address
     * @param dataIp            data IP address
     * @param state             node state
     * @param extNetwork        external network
     * @param podCidr           POD CIDR
     */
    protected DefaultK8sNode(String clusterName, String hostname, Type type,
                             int segmentId, Mode mode, DeviceId intgBridge,
                             DeviceId extBridge, DeviceId localBridge,
                             DeviceId tunBridge, String extIntf, IpAddress managementIp,
                             IpAddress dataIp, K8sNodeState state,
                             K8sExternalNetwork extNetwork, String podCidr) {
        this.clusterName = clusterName;
        this.hostname = hostname;
        this.type = type;
        this.mode = mode;
        this.segmentId = segmentId;
        this.intgBridge = intgBridge;
        this.extBridge = extBridge;
        this.localBridge = localBridge;
        this.tunBridge = tunBridge;
        this.extIntf = extIntf;
        this.managementIp = managementIp;
        this.dataIp = dataIp;
        this.state = state;
        this.extNetwork = extNetwork;
        this.podCidr = podCidr;
    }

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

    @Override
    public String hostShortName() {
        return StringUtils.substring(hostname, 0, SHORT_NAME_LENGTH);
    }

    @Override
    public String uniqueString(int length) {
        String uuid = UUID.nameUUIDFromBytes(hostname.getBytes()).toString();
        return StringUtils.substring(uuid, 0, length);
    }

    @Override
    public int segmentId() {
        return segmentId;
    }

    @Override
    public String tunnelKey() {
        if (mode == PASSTHROUGH) {
            return String.valueOf(segmentId);
        } else {
            return FLOW_KEY;
        }
    }

    @Override
    public Mode mode() {
        return mode;
    }

    @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 extBridge() {
        return extBridge;
    }

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

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

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

    @Override
    public K8sNode updateIntgBridge(DeviceId deviceId) {
        return new Builder()
                .hostname(hostname)
                .clusterName(clusterName)
                .type(type)
                .segmentId(segmentId)
                .mode(mode)
                .intgBridge(deviceId)
                .extBridge(extBridge)
                .localBridge(localBridge)
                .tunBridge(tunBridge)
                .extIntf(extIntf)
                .managementIp(managementIp)
                .dataIp(dataIp)
                .state(state)
                .extBridgeIp(extNetwork.extBridgeIp())
                .extGatewayIp(extNetwork.extGatewayIp())
                .extGatewayMac(extNetwork.extGatewayMac())
                .podCidr(podCidr)
                .build();
    }

    @Override
    public K8sNode updateExtBridge(DeviceId deviceId) {
        return new Builder()
                .hostname(hostname)
                .clusterName(clusterName)
                .type(type)
                .segmentId(segmentId)
                .mode(mode)
                .intgBridge(intgBridge)
                .extBridge(deviceId)
                .localBridge(localBridge)
                .tunBridge(tunBridge)
                .extIntf(extIntf)
                .managementIp(managementIp)
                .dataIp(dataIp)
                .state(state)
                .extBridgeIp(extNetwork.extBridgeIp())
                .extGatewayIp(extNetwork.extGatewayIp())
                .extGatewayMac(extNetwork.extGatewayMac())
                .podCidr(podCidr)
                .build();
    }

    @Override
    public K8sNode updateLocalBridge(DeviceId deviceId) {
        return new Builder()
                .hostname(hostname)
                .clusterName(clusterName)
                .type(type)
                .segmentId(segmentId)
                .mode(mode)
                .intgBridge(intgBridge)
                .extBridge(extBridge)
                .localBridge(deviceId)
                .tunBridge(tunBridge)
                .extIntf(extIntf)
                .managementIp(managementIp)
                .dataIp(dataIp)
                .state(state)
                .extBridgeIp(extNetwork.extBridgeIp())
                .extGatewayIp(extNetwork.extGatewayIp())
                .extGatewayMac(extNetwork.extGatewayMac())
                .podCidr(podCidr)
                .build();
    }

    @Override
    public K8sNode updateTunBridge(DeviceId deviceId) {
        return new Builder()
                .hostname(hostname)
                .clusterName(clusterName)
                .type(type)
                .segmentId(segmentId)
                .mode(mode)
                .intgBridge(intgBridge)
                .extBridge(extBridge)
                .localBridge(localBridge)
                .tunBridge(deviceId)
                .extIntf(extIntf)
                .managementIp(managementIp)
                .dataIp(dataIp)
                .state(state)
                .extBridgeIp(extNetwork.extBridgeIp())
                .extGatewayIp(extNetwork.extGatewayIp())
                .extGatewayMac(extNetwork.extGatewayMac())
                .podCidr(podCidr)
                .build();
    }

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

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

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

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

    @Override
    public K8sNode updateState(K8sNodeState newState) {
        return new Builder()
                .hostname(hostname)
                .clusterName(clusterName)
                .type(type)
                .segmentId(segmentId)
                .mode(mode)
                .intgBridge(intgBridge)
                .extBridge(extBridge)
                .localBridge(localBridge)
                .tunBridge(tunBridge)
                .extIntf(extIntf)
                .managementIp(managementIp)
                .dataIp(dataIp)
                .state(newState)
                .extBridgeIp(extNetwork.extBridgeIp())
                .extGatewayIp(extNetwork.extGatewayIp())
                .extGatewayMac(extNetwork.extGatewayMac())
                .podCidr(podCidr)
                .build();
    }

    @Override
    public K8sNode updateExtGatewayMac(MacAddress newMac) {
        return new Builder()
                .hostname(hostname)
                .clusterName(clusterName)
                .type(type)
                .segmentId(segmentId)
                .mode(mode)
                .intgBridge(intgBridge)
                .extBridge(extBridge)
                .localBridge(localBridge)
                .tunBridge(tunBridge)
                .extIntf(extIntf)
                .managementIp(managementIp)
                .dataIp(dataIp)
                .state(state)
                .extBridgeIp(extNetwork.extBridgeIp())
                .extGatewayIp(extNetwork.extGatewayIp())
                .extGatewayMac(newMac)
                .podCidr(podCidr)
                .build();
    }

    @Override
    public PortNumber grePortNum() {
        return tunnelPortNum(grePortName());
    }

    @Override
    public PortNumber vxlanPortNum() {
        return tunnelPortNum(vxlanPortName());
    }

    @Override
    public PortNumber genevePortNum() {
        return tunnelPortNum(genevePortName());
    }

    @Override
    public PortNumber intgBridgePortNum() {
        return portNumber(intgBridge, intgBridgePortName());
    }

    @Override
    public PortNumber intgToExtPatchPortNum() {
        return portNumber(intgBridge, intgToExtPatchPortName());
    }

    @Override
    public PortNumber intgToLocalPatchPortNum() {
        return portNumber(intgBridge, intgToLocalPatchPortName());

    }

    @Override
    public PortNumber localToIntgPatchPortNum() {
        return portNumber(localBridge, localToIntgPatchPortName());
    }

    @Override
    public PortNumber extToIntgPatchPortNum() {
        return portNumber(extBridge, extToIntgPatchPortName());
    }

    @Override
    public PortNumber intgToTunPortNum() {
        return portNumber(intgBridge, intgToTunPatchPortName());
    }

    @Override
    public PortNumber tunToIntgPortNum() {
        return portNumber(tunBridge, tunToIntgPatchPortName());
    }

    @Override
    public PortNumber extBridgePortNum() {
        if (this.extIntf == null) {
            return null;
        }
        return portNumber(extBridge, extBridgePortName());
    }

    @Override
    public MacAddress intgBridgeMac() {
        return macAddress(intgBridge, intgBridgeName());
    }

    @Override
    public IpAddress extBridgeIp() {
        return extNetwork.extBridgeIp();
    }

    @Override
    public MacAddress extBridgeMac() {
        return macAddress(extBridge, extBridgeName());
    }

    @Override
    public IpAddress extGatewayIp() {
        return extNetwork.extGatewayIp();
    }

    @Override
    public MacAddress extGatewayMac() {
        return extNetwork.extGatewayMac();
    }

    @Override
    public String grePortName() {
        if (mode == PASSTHROUGH) {
            return GRE_TUNNEL + "-" + segmentId;
        } else {
            return GRE_TUNNEL;
        }
    }

    @Override
    public String vxlanPortName() {
        if (mode == PASSTHROUGH) {
            return VXLAN_TUNNEL + "-" + segmentId;
        } else {
            return VXLAN_TUNNEL;
        }
    }

    @Override
    public String genevePortName() {
        if (mode == PASSTHROUGH) {
            return GENEVE_TUNNEL + "-" + segmentId;
        } else {
            return GENEVE_TUNNEL;
        }
    }

    @Override
    public String intgBridgeName() {
        if (mode == PASSTHROUGH) {
            return INTEGRATION_BRIDGE + "-" + uniqueString(5);
        } else {
            return INTEGRATION_BRIDGE;
        }
    }

    @Override
    public String extBridgeName() {
        if (mode == PASSTHROUGH) {
            return EXTERNAL_BRIDGE + "-" + uniqueString(5);
        } else {
            return EXTERNAL_BRIDGE;
        }
    }

    @Override
    public String localBridgeName() {
        if (mode == PASSTHROUGH) {
            return LOCAL_BRIDGE + "-" + uniqueString(5);
        } else {
            return LOCAL_BRIDGE;
        }
    }

    @Override
    public String tunBridgeName() {
        if (mode == PASSTHROUGH) {
            return TUNNEL_BRIDGE + "-" + segmentId;
        } else {
            return TUNNEL_BRIDGE;
        }
    }

    @Override
    public String intgBridgePortName() {
        if (mode == PASSTHROUGH) {
            return INTEGRATION_BRIDGE + "-" + uniqueString(5);
        } else {
            return INTEGRATION_BRIDGE;
        }
    }

    @Override
    public String extBridgePortName() {
        if (mode == PASSTHROUGH) {
            return EXTERNAL_BRIDGE + "-" + uniqueString(5);
        } else {
            return EXTERNAL_BRIDGE;
        }
    }

    @Override
    public String localBridgePortName() {
        if (mode == PASSTHROUGH) {
            return LOCAL_BRIDGE + "-" + uniqueString(5);
        } else {
            return LOCAL_BRIDGE;
        }
    }

    @Override
    public String tunBridgePortName() {
        if (mode == PASSTHROUGH) {
            return TUNNEL_BRIDGE + "-" + uniqueString(5);
        } else {
            return TUNNEL_BRIDGE;
        }
    }

    @Override
    public String intgToExtPatchPortName() {
        if (mode == PASSTHROUGH) {
            return INTEGRATION_TO_EXTERNAL_BRIDGE + "-" + uniqueString(5);
        } else {
            return INTEGRATION_TO_EXTERNAL_BRIDGE;
        }
    }

    @Override
    public String intgToTunPatchPortName() {
        if (mode == PASSTHROUGH) {
            return INTEGRATION_TO_TUN_BRIDGE + "-" + uniqueString(5);
        } else {
            return INTEGRATION_TO_TUN_BRIDGE;
        }
    }

    @Override
    public String intgToLocalPatchPortName() {
        if (mode == PASSTHROUGH) {
            return INTEGRATION_TO_LOCAL_BRIDGE + "-" + uniqueString(5);
        } else {
            return INTEGRATION_TO_LOCAL_BRIDGE;
        }
    }

    @Override
    public String localToIntgPatchPortName() {
        if (mode == PASSTHROUGH) {
            return LOCAL_TO_INTEGRATION_BRIDGE + "-" + uniqueString(5);
        } else {
            return LOCAL_TO_INTEGRATION_BRIDGE;
        }
    }

    @Override
    public String extToIntgPatchPortName() {
        if (mode == PASSTHROUGH) {
            return PHYSICAL_EXTERNAL_BRIDGE + "-" + uniqueString(5);
        } else {
            return PHYSICAL_EXTERNAL_BRIDGE;
        }
    }

    @Override
    public String tunToIntgPatchPortName() {
        if (mode == PASSTHROUGH) {
            return TUN_TO_INTEGRATION_BRIDGE + "-" + uniqueString(5);
        } else {
            return TUN_TO_INTEGRATION_BRIDGE;
        }
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }

        if (obj instanceof DefaultK8sNode) {
            DefaultK8sNode that = (DefaultK8sNode) obj;

            return clusterName.equals(that.clusterName) &&
                    hostname.equals(that.hostname) &&
                    type == that.type &&
                    segmentId == that.segmentId &&
                    mode == that.mode &&
                    intgBridge.equals(that.intgBridge) &&
                    extBridge.equals(that.extBridge) &&
                    localBridge.equals(that.localBridge) &&
                    tunBridge.equals(that.tunBridge) &&
                    extIntf.equals(that.extIntf) &&
                    managementIp.equals(that.managementIp) &&
                    dataIp.equals(that.dataIp) &&
                    extNetwork.equals(that.extNetwork) &&
                    podCidr.equals(that.podCidr) &&
                    state == that.state;
        }

        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(clusterName, hostname, type, segmentId, mode, intgBridge, extBridge,
                localBridge, tunBridge, extIntf, managementIp, dataIp, state, extNetwork, podCidr);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                .add("clusterName", clusterName)
                .add("hostname", hostname)
                .add("type", type)
                .add("segmentId", segmentId)
                .add("mode", mode)
                .add("intgBridge", intgBridge)
                .add("extBridge", extBridge)
                .add("localBridge", localBridge)
                .add("tunBridge", tunBridge)
                .add("extIntf", extIntf)
                .add("managementIp", managementIp)
                .add("dataIp", dataIp)
                .add("state", state)
                .add("extBridgeIp", extNetwork.extBridgeIp())
                .add("extGatewayIp", extNetwork.extGatewayIp())
                .add("extGatewayMac", extNetwork.extGatewayMac())
                .add("podCidr", podCidr)
                .toString();
    }

    private PortNumber tunnelPortNum(String tunnelType) {
        if (dataIp == null) {
            return null;
        }

        return portNumber(tunBridge, tunnelType);
    }

    private MacAddress macAddress(DeviceId deviceId, String portName) {
        Port port = port(deviceId, portName);
        Annotations annots = port.annotations();
        return annots != null ? MacAddress.valueOf(annots.value(PORT_MAC)) : null;
    }

    private PortNumber portNumber(DeviceId deviceId, String portName) {
        Port port = port(deviceId, portName);
        return port != null ? port.number() : null;
    }

    private Port port(DeviceId deviceId, String portName) {
        DeviceService deviceService = DefaultServiceDirectory.getService(DeviceService.class);
        return deviceService.getPorts(deviceId).stream()
                .filter(p -> p.isEnabled() &&
                        Objects.equals(p.annotations().value(PORT_NAME), portName))
                .findAny().orElse(null);
    }

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

    /**
     * Returns new builder instance with the given node as a default value.
     *
     * @param node kubernetes node
     * @return kubernetes node builder
     */
    public static Builder from(K8sNode node) {
        return new Builder()
                .hostname(node.hostname())
                .clusterName(node.clusterName())
                .type(node.type())
                .segmentId(node.segmentId())
                .intgBridge(node.intgBridge())
                .extBridge(node.extBridge())
                .localBridge(node.localBridge())
                .tunBridge(node.tunBridge())
                .extIntf(node.extIntf())
                .managementIp(node.managementIp())
                .dataIp(node.dataIp())
                .state(node.state())
                .extBridgeIp(node.extBridgeIp())
                .extGatewayIp(node.extGatewayIp())
                .extGatewayMac(node.extGatewayMac())
                .podCidr(node.podCidr());
    }

    public static final class Builder implements K8sNode.Builder {

        private String clusterName;
        private String hostname;
        private Type type;
        private int segmentId;
        private Mode mode;
        private DeviceId intgBridge;
        private DeviceId extBridge;
        private DeviceId localBridge;
        private DeviceId tunBridge;
        private IpAddress managementIp;
        private IpAddress dataIp;
        private K8sNodeState state;
        private K8sApiConfig apiConfig;
        private String extIntf;
        private IpAddress extBridgeIp;
        private IpAddress extGatewayIp;
        private MacAddress extGatewayMac;
        private String podCidr;

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

        @Override
        public K8sNode 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;
            }

            if (mode == null) {
                mode = NORMAL;
            }

            K8sExternalNetwork extNetwork = DefaultK8sExternalNetwork.builder()
                    .extBridgeIp(extBridgeIp)
                    .extGatewayIp(extGatewayIp)
                    .extGatewayMac(extGatewayMac)
                    .build();

            return new DefaultK8sNode(clusterName,
                    hostname,
                    type,
                    segmentId,
                    mode,
                    intgBridge,
                    extBridge,
                    localBridge,
                    tunBridge,
                    extIntf,
                    managementIp,
                    dataIp,
                    state,
                    extNetwork,
                    podCidr);
        }

        @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 segmentId(int segmentId) {
            this.segmentId = segmentId;
            return this;
        }

        @Override
        public Builder mode(Mode mode) {
            this.mode = mode;
            return this;
        }

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

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

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

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

        @Override
        public Builder extIntf(String intf) {
            this.extIntf = intf;
            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 state(K8sNodeState state) {
            this.state = state;
            return this;
        }

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

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

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

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