/*
 * Copyright 2018-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.openstacknetworking.impl;

import com.google.common.collect.ImmutableSet;
import org.apache.commons.lang.StringUtils;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.apache.http.Header;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpMessage;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpDelete;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicHttpResponse;
import org.onlab.packet.BasePacket;
import org.onlab.packet.Data;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.TCP;
import org.onlab.packet.TpPort;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.LeadershipService;
import org.onosproject.cluster.NodeId;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.packet.DefaultOutboundPacket;
import org.onosproject.net.packet.PacketContext;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
import org.onosproject.openstacknetworking.api.Constants;
import org.onosproject.openstacknetworking.api.InstancePort;
import org.onosproject.openstacknetworking.api.InstancePortService;
import org.onosproject.openstacknetworking.api.OpenstackFlowRuleService;
import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
import org.onosproject.openstacknode.api.OpenstackNode;
import org.onosproject.openstacknode.api.OpenstackNodeEvent;
import org.onosproject.openstacknode.api.OpenstackNodeListener;
import org.onosproject.openstacknode.api.OpenstackNodeService;
import org.openstack4j.model.network.Port;
import org.slf4j.Logger;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Objects;
import java.util.Set;

import static org.onosproject.openstacknetworking.api.Constants.DHCP_ARP_TABLE;
import static org.onosproject.openstacknetworking.api.Constants.PRIORITY_DHCP_RULE;
import static org.onosproject.openstacknetworking.impl.OpenstackMetadataProxyHandler.Http.Type.RESPONSE;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.hmacEncrypt;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.parseHttpRequest;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.unparseHttpResponseBody;
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.unparseHttpResponseHeader;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.CONTROLLER;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Handles metadata requests for the virtual instances.
 */
@Component(immediate = true)
public class OpenstackMetadataProxyHandler {
    protected final Logger log = getLogger(getClass());

    private static final String METADATA_SERVER_IP = "169.254.169.254";
    private static final int METADATA_SERVER_PORT = 8775;
    private static final int HTTP_SERVER_PORT = 80;
    private static final int PREFIX_LENGTH = 32;
    private static final short WINDOW_SIZE = (short) 0x1000;
    private static final short FIN_FLAG = (short) 0x01;
    private static final short SYN_FLAG = (short) 0x02;
    private static final short ACK_FLAG = (short) 0x10;
    private static final short SYN_ACK_FLAG = (short) 0x12;
    private static final short FIN_ACK_FLAG = (short) 0x11;
    private static final byte DATA_OFFSET = (byte) 0x5;
    private static final short URGENT_POINTER = (short) 0x1;
    private static final byte PACKET_TTL = (byte) 127;
    private static final String HTTP_PREFIX = "http://";
    private static final String COLON = ":";

    private static final String INSTANCE_ID_HEADER = "X-Instance-ID";
    private static final String INSTANCE_ID_SIGNATURE_HEADER = "X-Instance-ID-Signature";
    private static final String TENANT_ID_HEADER = "X-Tenant-ID";
    private static final String FORWARDED_FOR_HEADER = "X-Forwarded-For";

    private static final String HTTP_GET_METHOD = "GET";
    private static final String HTTP_POST_METHOD = "POST";
    private static final String HTTP_PUT_METHOD = "PUT";
    private static final String HTTP_DELETE_METHOD = "DELETE";

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected CoreService coreService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected PacketService packetService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected ClusterService clusterService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected LeadershipService leadershipService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected OpenstackNetworkService osNetworkService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected OpenstackNodeService osNodeService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected InstancePortService instancePortService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected OpenstackFlowRuleService osFlowRuleService;

    private final PacketProcessor packetProcessor = new InternalPacketProcessor();
    private final OpenstackNodeListener osNodeListener = new InternalNodeEventListener();

    private Set<String> excludedHeaders = ImmutableSet.of("content-type", "content-length");

    private ApplicationId appId;
    private NodeId localNodeId;

    @Activate
    protected void activate() {
        appId = coreService.registerApplication(Constants.OPENSTACK_NETWORKING_APP_ID);
        localNodeId = clusterService.getLocalNode().id();
        osNodeService.addListener(osNodeListener);
        packetService.addProcessor(packetProcessor, PacketProcessor.director(0));
        leadershipService.runForLeadership(appId.name());

        log.info("Started");
    }

    @Deactivate
    protected void deactivate() {
        packetService.removeProcessor(packetProcessor);
        osNodeService.removeListener(osNodeListener);
        leadershipService.withdraw(appId.name());

        log.info("Stopped");
    }

    private class InternalPacketProcessor implements PacketProcessor {

        @Override
        public void process(PacketContext context) {

            if (!useMetadataProxy()) {
                return;
            }

            if (context.isHandled()) {
                return;
            }

            Ethernet ethPacket = context.inPacket().parsed();
            if (ethPacket == null || ethPacket.getEtherType() != Ethernet.TYPE_IPV4) {
                return;
            }

            IPv4 ipv4Packet = (IPv4) ethPacket.getPayload();
            if (ipv4Packet.getProtocol() != IPv4.PROTOCOL_TCP ||
                    !IpAddress.valueOf(ipv4Packet.getDestinationAddress()).
                            equals(IpAddress.valueOf(METADATA_SERVER_IP))) {
                return;
            }

            TCP tcpPacket = (TCP) ipv4Packet.getPayload();
            if (tcpPacket.getDestinationPort() != HTTP_SERVER_PORT) {
                return;
            }

            // (three-way handshaking)
            // reply TCP SYN-ACK packet with receiving TCP SYN packet
            if (tcpPacket.getFlags() == SYN_FLAG) {
                Ethernet ethReply = buildTcpSynAckPacket(ethPacket, ipv4Packet, tcpPacket);
                sendReply(context, ethReply);
                return;
            }

            // (four-way handshaking)
            // reply TCP ACK and TCP FIN-ACK packets with receiving TCP FIN-ACK packet
            if (tcpPacket.getFlags() == FIN_ACK_FLAG) {
                Ethernet ackReply = buildTcpAckPacket(ethPacket, ipv4Packet, tcpPacket);
                sendReply(context, ackReply);
                Ethernet finAckReply = buildTcpFinAckPacket(ethPacket, ipv4Packet, tcpPacket);
                sendReply(context, finAckReply);
                return;
            }

            // normal TCP data transmission
            Data data = (Data) tcpPacket.getPayload();
            byte[] byteData = data.getData();

            if (byteData.length != 0) {
                HttpRequest request = parseHttpRequest(byteData);
                ConnectPoint cp = context.inPacket().receivedFrom();
                InstancePort instPort = instancePortService.instancePort(cp.deviceId(), cp.port());

                if (instPort == null || request == null) {
                    log.warn("Cannot send metadata request due to lack of information");
                    return;
                }

                // attempt to send HTTP request to the meta-data server (nova-api),
                // obtain the HTTP response, relay the response to VM through packet-out
                CloseableHttpResponse proxyResponse = proxyHttpRequest(request, instPort);

                if (proxyResponse == null) {
                    log.warn("No response was received from metadata server");
                    return;
                }

                HttpResponse response = new BasicHttpResponse(proxyResponse.getStatusLine());
                response.setEntity(proxyResponse.getEntity());
                response.setHeaders(proxyResponse.getAllHeaders());

                Http httpResponse = new Http();
                httpResponse.setType(RESPONSE);
                httpResponse.setMessage(response);

                TCP tcpReply = buildTcpDataPacket(tcpPacket, byteData.length, response);
                Ethernet ethReply = buildEthFrame(ethPacket, ipv4Packet, tcpReply);
                sendReply(context, ethReply);

                try {
                    proxyResponse.close();
                } catch (IOException e) {
                    log.warn("Failed to close the response connection due to {}", e);
                }
            }
        }

        /**
         * Builds an ethernet frame contains TCP sync-ack packet generated
         * from the given TCP sync request packet.
         *
         * @param ethRequest    ethernet request frame
         * @param ipv4Request   IPv4 request
         * @param tcpRequest    TCP request
         * @return an ethernet frame contains newly generated TCP reply
         */
        private Ethernet buildTcpSynAckPacket(Ethernet ethRequest,
                                              IPv4 ipv4Request, TCP tcpRequest) {

            TCP tcpReply = buildTcpSignalPacket(tcpRequest, tcpRequest.getSequence(),
                    tcpRequest.getSequence() + 1, SYN_ACK_FLAG);

            return buildEthFrame(ethRequest, ipv4Request, tcpReply);
        }

        /**
         * Builds a TCP ACK packet receiving SYN packet.
         *
         * @param ethRequest    ethernet request frame
         * @param ipv4Request   IPv4 request
         * @param tcpRequest    TCP request
         * @return an ethernet frame contains newly generated TCP reply
         */
        private Ethernet buildTcpAckPacket(Ethernet ethRequest,
                                           IPv4 ipv4Request, TCP tcpRequest) {
            TCP tcpReply = buildTcpSignalPacket(tcpRequest, tcpRequest.getAcknowledge(),
                    tcpRequest.getSequence() + 1, ACK_FLAG);

            return buildEthFrame(ethRequest, ipv4Request, tcpReply);
        }

        /**
         * Builds a TCP FIN-ACK packet receiving FIN-ACK packet.
         *
         * @param ethRequest    ethernet request frame
         * @param ipv4Request   IPv4 request
         * @param tcpRequest    TCP request
         * @return an ethernet frame contains newly generated TCP reply
         */
        private Ethernet buildTcpFinAckPacket(Ethernet ethRequest,
                                              IPv4 ipv4Request, TCP tcpRequest) {
            TCP tcpReply = buildTcpSignalPacket(tcpRequest, tcpRequest.getAcknowledge(),
                    tcpRequest.getSequence() + 1, FIN_ACK_FLAG);

            return buildEthFrame(ethRequest, ipv4Request, tcpReply);
        }

        /**
         * Builds a TCP signaling packet.
         *
         * @param tcpRequest    TCP request
         * @param seq           sequence number
         * @param ack           ack number
         * @param flags         TCP flags
         * @return TCP signal packet
         */
        private TCP buildTcpSignalPacket(TCP tcpRequest, int seq, int ack, short flags) {
            TCP tcpReply = new TCP();
            tcpReply.setSourcePort(tcpRequest.getDestinationPort());
            tcpReply.setDestinationPort(tcpRequest.getSourcePort());
            tcpReply.setSequence(seq);
            tcpReply.setAcknowledge(ack);
            tcpReply.setDataOffset(DATA_OFFSET);
            tcpReply.setFlags(flags);
            tcpReply.setWindowSize(WINDOW_SIZE);
            tcpReply.setUrgentPointer(URGENT_POINTER);

            return tcpReply;
        }

        /**
         * Builds a TCP data packet.
         *
         * @param tcpRequest    TCP request
         * @param requestLength TCP request data length
         * @param response      HTTP response
         * @return a TCP data packet
         */
        private TCP buildTcpDataPacket(TCP tcpRequest, int requestLength,
                                       HttpResponse response) {
            TCP tcpReply = new TCP();
            tcpReply.setSourcePort(tcpRequest.getDestinationPort());
            tcpReply.setDestinationPort(tcpRequest.getSourcePort());
            tcpReply.setSequence(tcpRequest.getAcknowledge());
            tcpReply.setAcknowledge(tcpRequest.getSequence() + requestLength);
            tcpReply.setDataOffset(DATA_OFFSET);        // no options
            tcpReply.setFlags(ACK_FLAG);
            tcpReply.setWindowSize(WINDOW_SIZE);
            tcpReply.setUrgentPointer(URGENT_POINTER);

            Http httpResponse = new Http();
            httpResponse.setType(RESPONSE);
            httpResponse.setMessage(response);

            tcpReply.setPayload(httpResponse);

            return tcpReply;
        }

        /**
         * Builds an ethernet frame with the given IPv4 and TCP payload.
         *
         * @param ethRequest    ethernet request frame
         * @param ipv4Request   IPv4 request
         * @param tcpReply      TCP reply
         * @return an ethernet frame contains TCP payload
         */
        private Ethernet buildEthFrame(Ethernet ethRequest, IPv4 ipv4Request,
                                       TCP tcpReply) {
            Ethernet ethReply = new Ethernet();
            ethReply.setSourceMACAddress(ethRequest.getDestinationMAC());
            ethReply.setDestinationMACAddress(ethRequest.getSourceMAC());
            ethReply.setEtherType(ethRequest.getEtherType());

            IPv4 ipv4Reply = new IPv4();
            ipv4Reply.setSourceAddress(ipv4Request.getDestinationAddress());
            ipv4Reply.setDestinationAddress(ipv4Request.getSourceAddress());
            ipv4Reply.setTtl(PACKET_TTL);

            ipv4Reply.setPayload(tcpReply);
            ethReply.setPayload(ipv4Reply);

            return ethReply;
        }

        /**
         * Obtains the metadata path.
         *
         * @param uri metadata request URI
         * @return full metadata path
         */
        private String getMetadataPath(String uri) {
            OpenstackNode controller = osNodeService.completeNodes(CONTROLLER).
                    stream().findFirst().orElse(null);
            if (controller == null) {
                return null;
            }

            String novaMetadataIpTmp = controller.neutronConfig().novaMetadataIp();
            String novaMetadataIp = novaMetadataIpTmp != null
                    ? novaMetadataIpTmp : controller.managementIp().toString();
            Integer novaMetadataPortTmp = controller.neutronConfig().novaMetadataPort();
            int novaMetadataPort = novaMetadataPortTmp != null
                    ? novaMetadataPortTmp : METADATA_SERVER_PORT;

            return HTTP_PREFIX + novaMetadataIp + COLON + novaMetadataPort + uri;
        }

        /**
         * Proxyies HTTP request.
         *
         * @param oldRequest    HTTP request
         * @param instPort      instance port
         * @return HTTP response
         */
        private CloseableHttpResponse proxyHttpRequest(HttpRequest oldRequest,
                                                       InstancePort instPort) {

            CloseableHttpClient client = HttpClientBuilder.create().build();
            String url = getMetadataPath(oldRequest.getRequestLine().getUri());

            if (StringUtils.isEmpty(url)) {
                log.warn("The metadata endpoint is not configured!");
                return null;
            }

            HttpRequestBase request;

            String method = oldRequest.getRequestLine().getMethod().toUpperCase();

            log.info("Sending HTTP {} request to metadata endpoint {}...", method, url);

            switch (method) {
                case HTTP_GET_METHOD:
                    request = new HttpGet(url);
                    break;
                case HTTP_POST_METHOD:
                    request = new HttpPost(url);
                    HttpEntityEnclosingRequest postRequest =
                            (HttpEntityEnclosingRequest) oldRequest;
                    ((HttpPost) request).setEntity(postRequest.getEntity());
                    break;
                case HTTP_PUT_METHOD:
                    request = new HttpPut(url);
                    HttpEntityEnclosingRequest putRequest =
                            (HttpEntityEnclosingRequest) oldRequest;
                    ((HttpPut) request).setEntity(putRequest.getEntity());
                    break;
                case HTTP_DELETE_METHOD:
                    request = new HttpDelete(url);
                    break;
                default:
                    request = new HttpGet(url);
                    break;
            }

            // configure headers from original HTTP request
            for (Header header : oldRequest.getAllHeaders()) {
                if (method.equals(HTTP_POST_METHOD) ||
                        method.equals(HTTP_PUT_METHOD)) {
                    // we DO NOT add duplicated HTTP headers for POST and PUT methods
                    if (excludedHeaders.contains(header.getName().toLowerCase())) {
                        continue;
                    }
                }
                request.addHeader(header);
            }

            request.setProtocolVersion(oldRequest.getProtocolVersion());

            Port port = osNetworkService.port(instPort.portId());

            request.addHeader(new BasicHeader(INSTANCE_ID_HEADER, port.getDeviceId()));
            request.addHeader(new BasicHeader(TENANT_ID_HEADER, port.getTenantId()));
            request.addHeader(new BasicHeader(FORWARDED_FOR_HEADER, instPort.ipAddress().toString()));
            if (metadataSecret() != null) {
                request.addHeader(new BasicHeader(INSTANCE_ID_SIGNATURE_HEADER,
                        hmacEncrypt(metadataSecret(), port.getDeviceId())));
            }

            try {
                return client.execute(request);
            } catch (IOException e) {
                log.warn("Failed to get response from metadata server due to {}", e);
            }

            return null;
        }

        /**
         * Sends out ethernet frame.
         *
         * @param context   packet context
         * @param ethReply  ethernet frame
         */
        private void sendReply(PacketContext context, Ethernet ethReply) {
            if (ethReply == null) {
                return;
            }
            ConnectPoint srcPoint = context.inPacket().receivedFrom();
            TrafficTreatment treatment = DefaultTrafficTreatment
                    .builder()
                    .setOutput(srcPoint.port())
                    .build();

            packetService.emit(new DefaultOutboundPacket(
                    srcPoint.deviceId(),
                    treatment,
                    ByteBuffer.wrap(ethReply.serialize())));
            context.block();
        }
    }

    private class InternalNodeEventListener implements OpenstackNodeListener {
        @Override
        public boolean isRelevant(OpenstackNodeEvent event) {
            // do not allow to proceed without leadership
            NodeId leader = leadershipService.getLeader(appId.name());
            return Objects.equals(localNodeId, leader) &&
                    event.subject().type() == COMPUTE && useMetadataProxy();
        }

        @Override
        public void event(OpenstackNodeEvent event) {
            OpenstackNode osNode = event.subject();
            switch (event.type()) {
                case OPENSTACK_NODE_COMPLETE:
                    setMetadataRule(osNode, true);
                    break;
                case OPENSTACK_NODE_INCOMPLETE:
                    setMetadataRule(osNode, false);
                    break;
                case OPENSTACK_NODE_CREATED:
                case OPENSTACK_NODE_UPDATED:
                case OPENSTACK_NODE_REMOVED:
                default:
                    break;
            }
        }

        /**
         * Installs metadata rule for receiving all metadata request packets.
         *
         * @param osNode    openstack node
         * @param install   installation flag
         */
        private void setMetadataRule(OpenstackNode osNode, boolean install) {
            TrafficSelector selector = DefaultTrafficSelector.builder()
                    .matchEthType(Ethernet.TYPE_IPV4)
                    .matchIPProtocol(IPv4.PROTOCOL_TCP)
                    .matchIPDst(IpPrefix.valueOf(
                            IpAddress.valueOf(METADATA_SERVER_IP), PREFIX_LENGTH))
                    .matchTcpDst(TpPort.tpPort(HTTP_SERVER_PORT))
                    .build();

            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
                    .punt()
                    .build();

            osFlowRuleService.setRule(
                    appId,
                    osNode.intgBridge(),
                    selector,
                    treatment,
                    PRIORITY_DHCP_RULE,
                    DHCP_ARP_TABLE,
                    install);
        }
    }

    private boolean useMetadataProxy() {
        OpenstackNode gw = osNodeService.completeNodes(CONTROLLER)
                .stream().findFirst().orElse(null);

        if (gw != null && gw.neutronConfig() != null) {
            return gw.neutronConfig().useMetadataProxy();
        }

        return false;
    }

    private String metadataSecret() {
        OpenstackNode controller = osNodeService.completeNodes(CONTROLLER)
                .stream().findFirst().orElse(null);

        if (controller != null && controller.neutronConfig() != null) {
            return controller.neutronConfig().metadataProxySecret();
        }

        return null;
    }

    /**
     * Implements Http packet format.
     */
    protected static class Http extends BasePacket {

        public enum Type {

            /**
             * Signifies that this is a Http REQUEST packet.
             */
            REQUEST,

            /**
             * Signifies that this is a Http RESPONSE packet.
             */
            RESPONSE,
        }

        private Type type;
        private HttpMessage message;

        /**
         * Obtains the Http type.
         *
         * @return Http type
         */
        public Type getType() {
            return type;
        }

        /**
         * Configures the Http type.
         *
         * @param type Http type
         */
        public void setType(Type type) {
            this.type = type;
        }

        /**
         * Obtains the Http message.
         *
         * @return Http message
         */
        public HttpMessage getMessage() {
            return message;
        }

        /**
         * Configures the Http message.
         *
         * @param message Http message
         */
        public void setMessage(HttpMessage message) {
            this.message = message;
        }

        @Override
        public byte[] serialize() {
            if (type == RESPONSE) {

                byte[] header = unparseHttpResponseHeader((HttpResponse) message);
                byte[] body = unparseHttpResponseBody((HttpResponse) message);

                if (header == null || body == null) {
                    return new byte[0];
                }

                final byte[] data = new byte[header.length + body.length];
                final ByteBuffer bb = ByteBuffer.wrap(data);
                bb.put(header);
                bb.put(body);

                return data;
            }
            return new byte[0];
        }

        @Override
        public boolean equals(Object o) {

            if (this == o) {
                return true;
            }

            if (o == null || getClass() != o.getClass()) {
                return false;
            }

            if (!super.equals(o)) {
                return false;
            }

            Http http = (Http) o;
            return type == http.type &&
                    com.google.common.base.Objects.equal(message, http.message);
        }

        @Override
        public int hashCode() {
            return Objects.hash(type, message);
        }
    }
}