/**
 * OCSF (Open Cybersecurity Schema Framework) v1.3 types for audit events.
 * See https://schema.ocsf.io/ for the full spec.
 *
 * We implement a subset relevant to Superblocks audit logging:
 * - Category 3: Identity & Access Management
 * - Category 6: Application Activity
 */

export enum OCSFCategoryUid {
  IAM = 3,
  APPLICATION_ACTIVITY = 6
}

export enum OCSFClassUid {
  ACCOUNT_CHANGE = 3001,
  AUTHENTICATION = 3002,
  ENTITY_MANAGEMENT = 3004,
  USER_ACCESS_MANAGEMENT = 3005,
  APPLICATION_LIFECYCLE = 6002,
  API_ACTIVITY = 6003
}

export enum OCSFActivityId {
  UNKNOWN = 0,
  CREATE = 1,
  READ = 2,
  UPDATE = 3,
  DELETE = 4,
  EXECUTE = 5,
  LOGIN = 6,
  LOGOUT = 7,
  DEPLOY = 8,
  GRANT = 9,
  REVOKE = 10,
  OTHER = 99
}

export enum OCSFStatusId {
  UNKNOWN = 0,
  SUCCESS = 1,
  FAILURE = 2,
  IN_PROGRESS = 99
}

export enum OCSFSeverityId {
  UNKNOWN = 0,
  INFORMATIONAL = 1,
  LOW = 2,
  MEDIUM = 3,
  HIGH = 4,
  CRITICAL = 5,
  FATAL = 6
}

export interface OCSFActor {
  user: {
    uid: string;
    name?: string;
    email_addr?: string;
    type?: string;
  };
  session?: {
    uid: string;
  };
}

export interface OCSFResource {
  uid: string;
  type: string;
  name?: string;
}

export interface OCSFApi {
  operation: string;
  service: {
    name: string;
  };
}

export interface OCSFMetadata {
  product: {
    name: string;
    vendor_name: string;
  };
  version: string;
  log_name: string;
}

/**
 * Core OCSF event shape stored in audit_event.data (jsonb).
 * `type_uid` = class_uid * 100 + activity_id (OCSF convention).
 */
export interface OCSFAuditEvent {
  category_uid: OCSFCategoryUid;
  class_uid: OCSFClassUid;
  activity_id: OCSFActivityId;
  type_uid: number;
  status_id: OCSFStatusId;
  severity_id: OCSFSeverityId;
  time: number;
  duration?: number;
  actor: OCSFActor;
  resource: OCSFResource;
  api?: OCSFApi;
  metadata: OCSFMetadata;
  unmapped?: Record<string, unknown>;
}

export function computeTypeUid(classUid: OCSFClassUid, activityId: OCSFActivityId): number {
  return classUid * 100 + activityId;
}

const METADATA: Omit<OCSFMetadata, 'log_name'> = {
  product: { name: 'Superblocks', vendor_name: 'Superblocks' },
  version: '1.3.0'
};

export function buildOCSFMetadata(logName: string): OCSFMetadata {
  return { ...METADATA, log_name: logName };
}
