/*
 * Copyright 2017-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.p4runtime.ctl;

import com.google.protobuf.ByteString;
import org.onlab.util.ImmutableByteSequence;
import org.onosproject.net.pi.model.PiPipeconf;
import org.onosproject.net.pi.runtime.PiPacketMetadata;
import org.onosproject.net.pi.runtime.PiPacketMetadataId;
import org.onosproject.net.pi.runtime.PiPacketOperation;
import org.slf4j.Logger;
import p4.config.P4InfoOuterClass;

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static org.onlab.util.ImmutableByteSequence.copyFrom;
import static org.onosproject.p4runtime.ctl.P4InfoBrowser.NotFoundException;
import static org.slf4j.LoggerFactory.getLogger;
import static p4.P4RuntimeOuterClass.PacketIn;
import static p4.P4RuntimeOuterClass.PacketMetadata;
import static p4.P4RuntimeOuterClass.PacketOut;

/**
 * Encoder of packet metadata, from ONOS Pi* format, to P4Runtime protobuf messages, and vice versa.
 */
final class PacketIOCodec {

    private static final Logger log = getLogger(PacketIOCodec.class);

    private static final String PACKET_OUT = "packet_out";

    private static final String PACKET_IN = "packet_in";

    // TODO: implement cache of encoded entities.

    private PacketIOCodec() {
        // hide.
    }

    /**
     * Returns a P4Runtime packet out protobuf message, encoded from the given PiPacketOperation
     * for the given pipeconf. If a PI packet metadata inside the PacketOperation cannot be encoded,
     * it is skipped, hence the returned PacketOut collection of metadatas might have different
     * size than the input one.
     * <p>
     * Please check the log for an explanation of any error that might have occurred.
     *
     * @param packet   PI packet operation
     * @param pipeconf the pipeconf for the program on the switch
     * @return a P4Runtime packet out protobuf message
     * @throws NotFoundException if the browser can't find the packet_out in the given p4Info
     */
    static PacketOut encodePacketOut(PiPacketOperation packet, PiPipeconf pipeconf)
            throws NotFoundException {

        //Get the P4browser
        P4InfoBrowser browser = PipeconfHelper.getP4InfoBrowser(pipeconf);

        //Get the packet out controller packet metadata
        P4InfoOuterClass.ControllerPacketMetadata controllerPacketMetadata =
                browser.controllerPacketMetadatas().getByName(PACKET_OUT);
        PacketOut.Builder packetOutBuilder = PacketOut.newBuilder();

        //outer controller packet metadata id
        int controllerPacketMetadataId = controllerPacketMetadata.getPreamble().getId();

        //Add all its metadata to the packet out
        packetOutBuilder.addAllMetadata(encodePacketMetadata(packet, browser, controllerPacketMetadataId));

        //Set the packet out payload
        packetOutBuilder.setPayload(ByteString.copyFrom(packet.data().asReadOnlyBuffer()));
        return packetOutBuilder.build();

    }

    private static List<PacketMetadata> encodePacketMetadata(PiPacketOperation packet,
                                                             P4InfoBrowser browser, int controllerPacketMetadataId) {
        return packet.metadatas().stream().map(metadata -> {
            try {
                //get each metadata id
                int metadataId = browser.packetMetadatas(controllerPacketMetadataId)
                        .getByName(metadata.id().name()).getId();

                //Add the metadata id and it's data the packet out
                return PacketMetadata.newBuilder()
                        .setMetadataId(metadataId)
                        .setValue(ByteString.copyFrom(metadata.value().asReadOnlyBuffer()))
                        .build();
            } catch (NotFoundException e) {
                log.error("Cant find metadata with name {} in p4Info file.", metadata.id().name());
                return null;
            }
        }).filter(Objects::nonNull).collect(Collectors.toList());
    }

    /**
     * Returns a PiPacketOperation, decoded from the given P4Runtime PacketIn protobuf message
     * for the given pipeconf. If a PI packet metadata inside the protobuf message cannot be decoded,
     * it is skipped, hence the returned PiPacketOperation collection of metadatas might have different
     * size than the input one.
     * <p>
     * Please check the log for an explanation of any error that might have occurred.
     *
     * @param packetIn the P4Runtime PAcketIn message
     * @param pipeconf the pipeconf for the program on the switch
     * @return a PiPacketOperation
     */
    static PiPacketOperation decodePacketIn(PacketIn packetIn, PiPipeconf pipeconf) {

        //Get the P4browser
        P4InfoBrowser browser = PipeconfHelper.getP4InfoBrowser(pipeconf);

        List<PiPacketMetadata> packetMetadatas;
        try {
            int controllerPacketMetadataId = browser.controllerPacketMetadatas().getByName(PACKET_IN)
                                                .getPreamble().getId();
            packetMetadatas = decodePacketMetadataIn(packetIn.getMetadataList(), browser,
                                                                            controllerPacketMetadataId);
        } catch (NotFoundException e) {
            log.error("Unable to decode packet metadatas: {}", e.getMessage());
            packetMetadatas = Collections.emptyList();
        }

        //Transform the packetIn data
        ImmutableByteSequence data = copyFrom(packetIn.getPayload().asReadOnlyByteBuffer());

        //Build the PiPacketOperation with all the metadatas.
        return PiPacketOperation.builder()
                .withType(PiPacketOperation.Type.PACKET_IN)
                .withMetadatas(packetMetadatas)
                .withData(data)
                .build();
    }

    private static List<PiPacketMetadata> decodePacketMetadataIn(List<PacketMetadata> packetMetadatas,
                                                               P4InfoBrowser browser, int controllerPacketMetadataId) {
        return packetMetadatas.stream().map(packetMetadata -> {
            try {

                int packetMetadataId = packetMetadata.getMetadataId();
                String packetMetadataName = browser.packetMetadatas(controllerPacketMetadataId)
                        .getById(packetMetadataId).getName();

                PiPacketMetadataId metadataId = PiPacketMetadataId.of(packetMetadataName);

                //Build each metadata.
                return PiPacketMetadata.builder()
                        .withId(metadataId)
                        .withValue(ImmutableByteSequence.copyFrom(packetMetadata.getValue().asReadOnlyByteBuffer()))
                        .build();
            } catch (NotFoundException e) {
                log.error("Cant find metadata with id {} in p4Info file.", packetMetadata.getMetadataId());
                return null;
            }
        }).filter(Objects::nonNull).collect(Collectors.toList());
    }

}
