// Copyright 2023 The gRPC authors.
//
// 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.

syntax = "proto3";

package fuzzer_input;

import "test/core/end2end/fuzzers/api_fuzzer.proto";
import "test/core/event_engine/fuzzing_event_engine/fuzzing_event_engine.proto";
import "test/core/test_util/fuzz_config_vars.proto";
import "test/core/test_util/fuzzing_channel_args.proto";

message Empty{};

message H2DataFrame {
    uint32 stream_id = 1;
    bool end_of_stream = 2;
    bytes payload = 3;
}

message SimpleHeader {
    // If key & value are set, then a literal unencoded header is added.
    optional string key = 1;
    optional string value = 2;
    // If raw_bytes is set, then after the key/value pair (if emitted) the raw bytes are emitted.
    optional bytes raw_bytes = 3;
}

message SimpleHeaders {
    repeated SimpleHeader headers = 1;

    optional string grpc_timeout = 2;
    optional string te = 3;
    optional string content_type = 4;
    optional string scheme = 5; 
    optional string method = 6;
    optional string grpc_encoding = 7;
    optional string grpc_internal_encoding_request = 8;
    optional string grpc_accept_encoding = 9;
    optional string user_agent = 10;
    optional string grpc_message = 11;
    optional string host = 12;
    optional string endpoint_load_metrics_bin = 13;
    optional string grpc_server_stats_bin = 14;
    optional string grpc_trace_bin = 15;
    optional string grpc_tags_bin = 16;
    optional string x_envoy_peer_metadata = 17;
    optional string authority = 18;
    optional string path = 19;
    optional string grpc_status = 20;
    optional string grpc_previous_rpc_attempts = 21;
    optional string grpc_retry_pushback_ms = 22;
    optional string status = 23;
    optional string grpclb_client_stats = 24;
    optional string lb_token = 25;
    optional string lb_cost_bin = 26;

    optional string chaotic_good_connection_type = 27;
    optional string chaotic_good_connection_id = 28;
    optional string chaotic_good_alignment = 29;
}

message H2HeaderFrame {
    uint32 stream_id = 1;
    bool end_headers =  2;
    bool end_stream = 3;
    oneof payload {
        bytes raw_bytes = 5;
        SimpleHeaders simple_header = 6;
    }
}

message H2ContinuationFrame {
    uint32 stream_id = 1;
    bool end_headers =  2;
    oneof payload {
        bytes raw_bytes = 5;
        SimpleHeaders simple_header = 6;
    }
}

message H2RstStreamFrame {
    uint32 stream_id = 1;
    uint32 error_code = 2;
}

message H2Setting {
    uint32 id = 1;
    uint32 value = 2;
}

message H2SettingsFrame {
    bool ack = 1;
    repeated H2Setting settings = 2;
}

message H2PingFrame {
    bool ack = 1;
    uint64 opaque = 2;
}

message H2GoawayFrame {
    uint32 last_stream_id = 1;
    uint32 error_code = 2;
    bytes debug_data = 3;
}

message H2WindowUpdateFrame {
    uint32 stream_id = 1;
    uint32 increment = 2;
}

message H2ClientPrefix {}

message ChaoticGoodServerFragment {
    uint32 stream_id = 1;
    oneof headers {
        Empty headers_none = 11;
        bytes headers_raw_bytes = 12;
        SimpleHeaders headers_simple_header = 13;
    }
    oneof data {
        Empty none = 21;
        uint32 length = 22;
    }
    oneof trailers {
        Empty trailers_none = 31;
        bytes trailers_raw_bytes = 32;
        SimpleHeaders trailers_simple_header = 33;
    }
}

message ChaoticGoodMessageData {
    uint32 length = 1;
    uint32 padding = 2;
}

message ChaoticGoodFrame {
    enum FrameType {
        SETTINGS = 0;
        FRAGMENT = 1;
        CANCEL = 2;
    };
    uint32 stream_id = 1;
    FrameType type = 2;
    oneof headers {
        Empty headers_none = 11;
        bytes headers_raw_bytes = 12;
        SimpleHeaders headers_simple_header = 13;
    }
    oneof data {
        Empty data_none = 21;
        ChaoticGoodMessageData data_sized = 23;
    }
    oneof trailers {
        Empty trailers_none = 31;
        bytes trailers_raw_bytes = 32;
        SimpleHeaders trailers_simple_header = 33;
    }
}

message ChaoticGoodSettings {}

message InputSegment {
    int32 delay_ms = 1;
    oneof payload {
        bytes raw_bytes = 2;
        H2DataFrame data = 3;
        H2HeaderFrame header = 4;
        H2ContinuationFrame continuation = 5;
        H2RstStreamFrame rst_stream = 6;
        H2SettingsFrame settings = 7;
        H2PingFrame ping = 8;
        H2GoawayFrame goaway = 9;
        H2WindowUpdateFrame window_update = 10;
        H2ClientPrefix client_prefix = 11;
        uint32 repeated_zeros = 12;
        ChaoticGoodFrame chaotic_good = 13;
    }
}

message InputSegments {
    repeated InputSegment segments = 1;
}

message NetworkInput {
    int32 connect_delay_ms = 3;
    int32 connect_timeout_ms = 4;
    grpc.testing.FuzzingChannelArgs endpoint_config = 5;
    oneof value {
        bytes single_read_bytes = 1;
        InputSegments input_segments = 2;
    }
}

message Msg {
    repeated NetworkInput network_input = 1;
    repeated api_fuzzer.Action api_actions = 2;
    fuzzing_event_engine.Actions event_engine_actions = 3;
    grpc.testing.FuzzConfigVars config_vars = 4;
    grpc.testing.FuzzingChannelArgs channel_args = 5;
}
