syntax = "proto3";

package conduit.common;

import "google/protobuf/duration.proto";

message HttpMethod {
  enum Registered {
    GET = 0;
    POST = 1;
    PUT = 2;
    DELETE = 3;
    PATCH = 4;
    OPTIONS = 5;
    CONNECT = 6;
    HEAD = 7;
    TRACE = 8;
  }

  oneof type {
    Registered registered = 1;
    string unregistered = 2;
  }
}

message Scheme {
  enum Registered {
    HTTP = 0;
    HTTPS = 1;
  }

  oneof type {
    Registered registered = 1;
    string unregistered = 2;
  }
}

message IPAddress {
  oneof ip {
    fixed32 ipv4 = 1;
    IPv6 ipv6 = 2;
  }
}

message IPv6 {
  fixed64 first = 1; // hextets 1-4
  fixed64 last = 2; // hextets 5-8
}

message TcpAddress {
  IPAddress ip = 1;
  uint32 port = 2;
}

message Destination {
  string scheme = 1; // such as "DNS" or "K8S"
  string path = 2;
}

message Eos {
  oneof end {
    uint32 grpc_status_code = 1;
    uint32 reset_error_code = 2;
  }
}

message TapEvent {
  TcpAddress source = 1;

  TcpAddress   destination      = 2;
  EndpointMeta destination_meta = 4;

  oneof event {
    Http http = 3;
  }

  message EndpointMeta {
    map<string, string> labels = 1;
  }

  message Http {
    oneof event {
      RequestInit  request_init  = 1;
      ResponseInit response_init = 2;
      ResponseEnd  response_end  = 3;
    }

    message StreamId {
      // A randomized base (stable across a process's runtime)
      uint32 base = 1;

      // A stream id unique within the lifetime of `base`.
      uint64 stream = 2;
    }

    message RequestInit {
      StreamId id = 1;
      HttpMethod method =  2;
      Scheme scheme = 3;
      string authority = 4;
      string path = 5;
      // TODO headers
    }

    message ResponseInit {
      StreamId id = 1;

      google.protobuf.Duration since_request_init = 2;

      uint32 http_status = 3;
    }

    message ResponseEnd {
      StreamId id = 1;

      google.protobuf.Duration since_request_init = 2;
      google.protobuf.Duration since_response_init = 3;
      uint64 response_bytes = 4;

      Eos eos = 5;
    }
  }
}

enum Protocol {
  HTTP = 0;
  TCP = 1;
}
