import { ARID } from "./policy.js";
import { Session, User, UserId } from "./user.js";

/**
 * The outcome of a log event. Should always be populated.
 */
export enum Outcome {
    /**
     * The event is unfolding at the time that you create the log entry.
     */
    IN_PROGRESS = "IN_PROGRESS",
    /**
     * The event has completed successfully.
     */
    SUCCESS = "SUCCESS",
    /**
     * The event has completed unsuccessfully.
     */
    FAILURE = "FAILURE",
    /**
     * The event has completed. For events that don't fit into SUCCESS or FAILURE.
     */
    COMPLETED = "COMPLETED"
}

/**
 * Options for logging an event. Should always be populated, since outcome is always required.
 */
export interface LogOptions {
    /**
     * The outcome of the event that you're logging.
     */
    outcome: Outcome;
    /**
     * The severity of the event that you're logging. 
     * 
     * Think: Will this cause system disruption? How severe?
     * Will default to INFO if not provided.
     */
    severity?: Severity;
    /**
     * The resources associated with/affected by the event that you're logging.
     * Should be populated any time resources are in scope.
     */
    associatedResources?: ARID[];
    /**
     * The users associated with/affected by the event that you're logging.
     * Should be populated any time users are in scope.
     */
    associatedUsers?: User[] | UserId[];
    /**
     * The session of the user associated with the event that you're logging.
     * Should be populated any time a user session is in scope.
     */
    session?: Session;
    /**
     * Additional context to include with the log message.
     */
    context?: string;
    /**
     * Privileged information to include with the log message. Should include
     * things like stack traces, PII (that isn't covered by other fields), etc.
     */
    sensitiveContext?: string;
    /**
     * The type of event that you're logging.
     */
    eventType: EventType;
}

/**
 * The type of event that you're logging. Should be defined by you in 
 * your code.
 */
export type EventType = string & { __brand: "EventType" };

/**
 * The severity of the event that you're logging
 */
export enum Severity {
    /**
     * Only interesting to developers. Causes no disruption and represents no deviation.
     */
    DEBUG = 0,
    /**
     * Informational messages that highlight the progress of the application at coarse-grained level.
     */
    INFO = 1,
    /**
     * Normal but significant events. (i.e. user accesses a privileged location)
     */
    NOTICE = 2,
    /**
     * Exceptional occurrences that are not errors. (i.e. user attempts to access a privileged location but is denied)
     */
    WARNING = 3,
    /**
     * Occurrences that do not require immediate action but should typically be logged and monitored.
     * Will flag for human review but not immediate action.
     */
    ERROR = 4,
    /**
     * Critical conditions. (i.e. application component unavailable)
     * Will page a human to address the issue.
     */
    CRITICAL = 5
}

