/*
 * 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.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 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);

        //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(decodePacketMetadata(packetIn.getMetadataList(), browser))
                .withData(data)
                .build();
    }

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

                int controllerPacketMetadataId = packetMetadata.getMetadataId();
                //convert id to name through p4Info
                P4InfoOuterClass.ControllerPacketMetadata metadata =
                        browser.controllerPacketMetadatas().getById(controllerPacketMetadataId);
                PiPacketMetadataId metadataId = PiPacketMetadataId.of(metadata.getPreamble().getName());

                //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());
    }

}
