/**
 * Represents a resource in the Archon policy engine.
 */
export type ArchonResourceId = string & { __brand: "ArchonResourceId" };
/**
 * Represents a resource in the Archon policy engine. Alias for ArchonResourceId.
 */
export type ARID = ArchonResourceId;
/**
 * Represents the name of a resource type in the Archon policy engine.
 */
export type ResourceTypeName = string & { __brand: "ResourceTypeName" };
/**
 * Represents an intent of a resource in the Archon policy engine.
 */
export type ResourceIntentName = string & { __brand: "ResourceIntentName" };
/**
 * Represents the name of a role in the Archon policy engine.
 */
export type RoleName = string & { __brand: "RoleName" };

/**
 * An intent is a way to access a resource. Intents are defined in the archon.yaml file.
 * 
 * For instance, a user may have a "read-conversation" intent to read a conversation resource.
 */
export interface ResourceIntent {
    /**
     * The name of the intent, defined in the archon.yaml file.
     */
    name: ResourceIntentName;
    /**
     * A human-readable description of the intent, defined in the archon.yaml file.
     */
    description?: string;
};

/**
 * A role in the Archon policy engine. This will not include the permissions associated with the role.
 * These permissions can only be managed via the Archon policy service or editing archon.yaml.
 */
export interface Role {
    /**
     * The name of the role, defined in the archon.yaml file.
     */
    name: RoleName;
    /**
     * A human-readable description of the role, defined in the archon.yaml file.
     */
    description?: string;
    /**
     * Whether the role is privileged. Privileged roles require reauthentication to switch to.
     */
    privileged: boolean;
    /**
     * The parent role of this role, if any. If this role has no parent, this field will be omitted.
     */
    parent?: Role;
}

/**
 * Represents a resource entity with metadata and type association.
 */
export interface Resource {
    /**
     * The unique identifier for the resource.
     * @remarks Auto-incremented by the database.
     */
    id: number;

    /**
     * The unique ARID (Archon Resource Identifier) for the resource.
     * @remarks This is a UUID and must be unique.
     */
    arid: ARID;

    /**
     * The type of the resource.
     * @remarks This is a relation to the `ResourceType` entity.
     */
    type: ResourceType;

    /**
     * The metadata associated with the resource.
     * @remarks Stored as a JSON object, defaults to an empty object `{}`.
     */
    metadata: Record<string, unknown>;
}

/**
 * The result of an access determination operation.
 */
export interface AccessDetermination {
    /**
     * Whether the user is allowed to access the resource with the given intent.
     */
    allowed: boolean;
    /**
     * If the user could access this resource using another role, this field may contain the roles.
     */
    accessibleVia?: Role[];
    /**
     * If the user is not allowed to access the resource, this field may contain a human-readable explanation of why.
     * If the user is allowed to access the resource, this field will be omitted.
     */
    reason?: string;
}

/**
 * The options for adding a new resource to the Archon policy engine.
 */
export interface AddResourceOptions {
    /**
     * User-defined metadata to attach to the new resource. Must be a JSON-serializable object.
     */
    metadata?: object;
    /**
     * The resource type of the new resource.
     */
    type: ResourceType | ResourceTypeName;
}

/**
 * Information about a resource type, as defined in the archon.yaml file.
 */
export interface ResourceType {
    /**
     * The name of the resource type, defined in the archon.yaml file.
     */
    name: ResourceTypeName;
    /**
     * A human-readable description of the resource type, defined in the archon.yaml file.
     */
    description?: string;
    /**
     * The intents that can be used to access resources of this type, if any are defined in the archon.yaml file.
     */
    intents?: ResourceIntent[];
    /**
     * Parent resource type, if any. If this resource type has no parent, this field will be omitted.
     */
    parentName?: string;
    /**
     * If this resource type is a singleton, this field is the ARID of the singleton resource.
     * If this resource type is not a singleton, this field will be omitted.
     */
    singleton?: ARID;
}