#include <core.p4>
#include <sume_switch.p4>
#include "headers.p4"


#define Parsed_packet headers
#define user_metadata_t metadata

// 1500 mtu * 8 = 12000
#define MAX_NETPFGA_PACKET_SIZE_BITS 16384

// digest_data, MUST be 256 bits -- not using it
struct digest_data_t {
    bit<256> unused;
}

/********************************************************************************
 * Parser
*/
parser RealParser(
    packet_in packet,
    out Parsed_packet hdr,
    out user_metadata_t meta,
    out digest_data_t digest_data,
    inout sume_metadata_t standard_metadata) {


    #include "parsers.p4"
}

@Xilinx_MaxPacketRegion(MAX_NETPFGA_PACKET_SIZE_BITS)
parser TopParser(
    packet_in b,
    out Parsed_packet p,
    out user_metadata_t user_metadata,
    out digest_data_t digest_data,
    inout sume_metadata_t sume_metadata) {

    RealParser() realparser;

    state start {
        realparser.apply(b, p, user_metadata, digest_data, sume_metadata);
        transition accept;
    }
}

/********************************************************************************
 * Main
*/

control RealMain(
    inout Parsed_packet hdr,
    inout user_metadata_t meta,
    inout digest_data_t digest_data,
    inout sume_metadata_t sume_metadata) {

    #include "actions_nat64_generic.p4"
    #include "actions_egress.p4"
    #include "actions_delta_checksum.p4"

    //#include "netpfga_dummy.p4"

    apply {
        bit<17> tmp17 = 0;

        /* does not compile without a table - give it a table */
        //dummy_table_for_netpfga.apply();

        /* continue without tables */
        //#include "netpfga_nat64_stupid_hardcoded.p4"

        #include "netpfga_nat64.p4"

    }

}

control TopPipe(
    inout Parsed_packet p,
    inout user_metadata_t user_metadata,
    inout digest_data_t digest_data,
    inout sume_metadata_t sume_metadata) {

    RealMain() realmain;

    apply {
        realmain.apply(p, user_metadata, digest_data, sume_metadata);
    }
}

/********************************************************************************
 * Deparser
 */

control RealDeParser(
    packet_out packet,
    in Parsed_packet hdr,
    in user_metadata_t meta,
    inout digest_data_t digest_data,
    inout sume_metadata_t sume_metadata) {

    #include "deparser.p4"
}

@Xilinx_MaxPacketRegion(MAX_NETPFGA_PACKET_SIZE_BITS)
control TopDeparser(
    packet_out b,
    in Parsed_packet p,
    in user_metadata_t user_metadata,
    inout digest_data_t digest_data,
    inout sume_metadata_t sume_metadata) {

    RealDeParser() realdeparser;

    apply {
        realdeparser.apply(b, p, user_metadata, digest_data, sume_metadata);
    }

}

/********************************************************************************
 * Switch
 */

SimpleSumeSwitch(
    TopParser(),
    TopPipe(),
    TopDeparser()
) main;
