syntax = "proto3";

package golem.apidefinition;

import "golem/rib/expr.proto";
import "golem/rib/rib_input.proto";
import "golem/rib/rib_output.proto";
import "golem/rib/rib_byte_code.proto";
import "golem/rib/worker_functions_in_rib.proto";
import "golem/component/versioned_component_id.proto";
import "google/protobuf/timestamp.proto";

// Used in api definition repo and needs to be backward compatible
message ApiDefinition {
  ApiDefinitionId id = 1;
  string version = 2;
  oneof definition {
    HttpApiDefinition http = 3;
  }
  bool draft = 4;
  google.protobuf.Timestamp created_at = 5;
}

// Used in api definition repo and needs to be backward compatible
message ApiDefinitionList {
  repeated ApiDefinition definitions = 1;
}

// Used in api definition repo and needs to be backward compatible
message HttpApiDefinition {
  repeated HttpRoute routes = 1;
}

// Used in api definition repo and needs to be backward compatible
message SecuritySchemeReference {
  string security_scheme_identifier = 1;
}

// Used in api definition repo and needs to be backward compatible
message CompiledHttpApiDefinition {
  repeated CompiledHttpRoute routes = 1;
}

// Used in api definition repo and needs to be backward compatible
message ApiDefinitionId {
  string value = 1;
}

// Used in api definition repo and needs to be backward compatible
message HttpRoute {
  HttpMethod method = 1;
  string path = 2;
  GatewayBinding binding = 3;
  Middleware middleware = 4;
}

// Used in api definition repo and needs to be backward compatible
message CompiledHttpRoute {
   HttpMethod method = 1;
   string path = 2;
   CompiledGatewayBinding binding = 3;
   Middleware middleware = 4;
}

// Used in api definition repo and needs to be backward compatible
enum HttpMethod {
  GET = 0;
  CONNECT = 1;
  POST = 2;
  DELETE = 3;
  PUT = 4;
  PATCH = 5;
  OPTIONS = 6;
  TRACE = 7;
  HEAD = 8;
}

// Used in api definition repo and needs to be backward compatible
message GatewayBinding {
  // Optional field to keep backward compatibility
  optional golem.component.VersionedComponentId component = 1;
  optional golem.rib.Expr worker_name = 2;
  // Optional field to keep backward compatibility
  optional golem.rib.Expr response = 3;
  optional golem.rib.Expr idempotency_key = 4;
  // type discriminator to keep backward compatibility
  optional GatewayBindingType binding_type = 5;
  optional StaticBinding static_binding = 6;
  optional golem.rib.Expr invocation_context = 7;
}

// Used in api definition repo and needs to be backward compatible
message CompiledGatewayBinding {
    // Optional field to keep backward compatibility
    optional golem.component.VersionedComponentId component = 1;
    optional golem.rib.Expr worker_name = 2;
    optional golem.rib.RibByteCode compiled_worker_name_expr = 3;
    optional golem.rib.RibInputType worker_name_rib_input = 4;
    optional golem.rib.Expr response = 5;
    optional golem.rib.RibByteCode compiled_response_expr = 6;
    optional golem.rib.RibInputType response_rib_input = 7;
    optional golem.rib.Expr idempotency_key = 8;
    optional golem.rib.RibByteCode compiled_idempotency_key_expr = 9;
    optional golem.rib.RibInputType idempotency_key_rib_input = 10;
    optional golem.rib.WorkerFunctionsInRib worker_functions_in_response = 11;
    // type discriminator to keep backward compatibility
    optional GatewayBindingType binding_type = 12;
    optional StaticBinding static_binding = 13;
    optional golem.rib.RibOutputType response_rib_output = 14;
    optional golem.rib.Expr invocation_context = 15;
    optional golem.rib.RibByteCode compiled_invocation_context_expr = 16;
    optional golem.rib.RibInputType invocation_context_rib_input = 17;
}

message SecuritySchemaReference {
    string security_scheme_identifier = 1;
}

// Used in api definition repo and needs to be backward compatible
enum GatewayBindingType {
  DEFAULT = 0;
  FILE_SERVER = 1;
  CORS_PREFLIGHT = 2;
  AUTH_CALL_BACK = 3;
  HTTP_HANDLER = 4;
}

// Used in api definition repo and needs to be backward compatible
message Middleware {
  optional CorsPreflight cors = 1;
  optional SecurityWithProviderMetadata http_authentication = 2;
}

// Used in api definition repo and needs to be backward compatible
message StaticBinding {
  oneof static_binding {
    CorsPreflight http_cors_preflight = 1;
    AuthCallBack auth_callback = 2;
  }
}

message AuthCallBack {
  SecurityWithProviderMetadata security_with_provider_metadata = 1;
}

// Used in api definition repo and needs to be backward compatible
message CorsPreflight {
  optional string allow_origin = 1;
  optional string allow_methods = 2;
  optional string allow_headers = 3;
  optional string expose_headers = 4;
  optional uint64 max_age = 5;
  optional bool allow_credentials = 6;
}

message SecurityWithProviderMetadata {
  SecurityScheme security_scheme = 1;
  IdentityProviderMetadata identity_provider_metadata = 2;
}

message SecurityScheme {
  Provider provider = 1;
  string scheme_identifier = 2;
  string client_id = 3;
  string client_secret = 4;
  string redirect_url = 5;
  repeated string scopes = 6;
}

message Provider {
  oneof provider {
    Google google = 1;
    Facebook facebook = 2;
    Microsoft microsoft = 3;
    Gitlab gitlab = 4;
  }
}

message Google{}
message Facebook{}
message Microsoft{}
message Gitlab{}

message IdentityProviderMetadata {
  string metadata = 1;
}
