syntax = "proto3";

package proto;

option csharp_namespace = "DysonNetwork.Shared.Proto";

import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
import "google/protobuf/struct.proto";

import 'account.proto';

// Represents a user session
message AuthSession {
  string id = 1;
  optional google.protobuf.Timestamp last_granted_at = 3;
  optional google.protobuf.Timestamp expired_at = 4;
  string account_id = 5;
  Account account = 6;
  string challenge_id = 7;
  AuthChallenge challenge = 8;
  google.protobuf.StringValue app_id = 9;
}

// Represents an authentication challenge
message AuthChallenge {
  string id = 1;
  google.protobuf.Timestamp expired_at = 2;
  int32 step_remain = 3;
  int32 step_total = 4;
  int32 failed_attempts = 5;
  ChallengeType type = 7;
  repeated string blacklist_factors = 8;
  repeated string audiences = 9;
  repeated string scopes = 10;
  google.protobuf.StringValue ip_address = 11;
  google.protobuf.StringValue user_agent = 12;
  google.protobuf.StringValue device_id = 13;
  google.protobuf.StringValue nonce = 14;
  // Point location is omitted as there is no direct proto equivalent.
  string account_id = 15;
}

// Enum for challenge types
enum ChallengeType {
  CHALLENGE_TYPE_UNSPECIFIED = 0;
  LOGIN = 1;
  OAUTH = 2;
  OIDC = 3;
}

// Enum for challenge platforms
enum ChallengePlatform {
  CHALLENGE_PLATFORM_UNSPECIFIED = 0;
  UNIDENTIFIED = 1;
  WEB = 2;
  IOS = 3;
  ANDROID = 4;
  MACOS = 5;
  WINDOWS = 6;
  LINUX = 7;
}

service AuthService {
  rpc Authenticate(AuthenticateRequest) returns (AuthenticateResponse) {}
  
  rpc ValidatePin(ValidatePinRequest) returns (ValidateResponse) {}
  rpc ValidateCaptcha(ValidateCaptchaRequest) returns (ValidateResponse) {}
}

message AuthenticateRequest {
  string token = 1;
}

message AuthenticateResponse {
  bool valid = 1;
  optional string message = 2;
  optional AuthSession session = 3;
}

message ValidatePinRequest {
  string account_id = 1;
  string pin = 2;
}

message ValidateCaptchaRequest {
  string token = 1;
}

message ValidateResponse {
  bool valid = 1;
}

// Permission related messages and services
message PermissionNode {
  string id = 1;
  string actor = 2;
  string area = 3;
  string key = 4;
  google.protobuf.Value value = 5; // Using Value to represent generic type
  google.protobuf.Timestamp expired_at = 6;
  google.protobuf.Timestamp affected_at = 7;
  string group_id = 8; // Optional group ID
}

message PermissionGroup {
  string id = 1;
  string name = 2;
  google.protobuf.Timestamp created_at = 3;
}

message HasPermissionRequest {
  string actor = 1;
  string area = 2;
  string key = 3;
}

message HasPermissionResponse {
  bool has_permission = 1;
}

message GetPermissionRequest {
  string actor = 1;
  string area = 2;
  string key = 3;
}

message GetPermissionResponse {
  google.protobuf.Value value = 1; // Using Value to represent generic type
}

message AddPermissionNodeRequest {
  string actor = 1;
  string area = 2;
  string key = 3;
  google.protobuf.Value value = 4;
  google.protobuf.Timestamp expired_at = 5;
  google.protobuf.Timestamp affected_at = 6;
}

message AddPermissionNodeResponse {
  PermissionNode node = 1;
}

message AddPermissionNodeToGroupRequest {
  PermissionGroup group = 1;
  string actor = 2;
  string area = 3;
  string key = 4;
  google.protobuf.Value value = 5;
  google.protobuf.Timestamp expired_at = 6;
  google.protobuf.Timestamp affected_at = 7;
}

message AddPermissionNodeToGroupResponse {
  PermissionNode node = 1;
}

message RemovePermissionNodeRequest {
  string actor = 1;
  string area = 2;
  string key = 3;
}

message RemovePermissionNodeResponse {
  bool success = 1;
}

message RemovePermissionNodeFromGroupRequest {
  PermissionGroup group = 1;
  string actor = 2;
  string area = 3;
  string key = 4;
}

message RemovePermissionNodeFromGroupResponse {
  bool success = 1;
}

service PermissionService {
  rpc HasPermission(HasPermissionRequest) returns (HasPermissionResponse) {}
  rpc GetPermission(GetPermissionRequest) returns (GetPermissionResponse) {}
  rpc AddPermissionNode(AddPermissionNodeRequest) returns (AddPermissionNodeResponse) {}
  rpc AddPermissionNodeToGroup(AddPermissionNodeToGroupRequest) returns (AddPermissionNodeToGroupResponse) {}
  rpc RemovePermissionNode(RemovePermissionNodeRequest) returns (RemovePermissionNodeResponse) {}
  rpc RemovePermissionNodeFromGroup(RemovePermissionNodeFromGroupRequest) returns (RemovePermissionNodeFromGroupResponse) {}
}

