import { Request, Response, NextFunction } from 'express';
import Logger from 'bunyan';
import { ApiConfig, AuthenticationClient } from '@ministryofjustice/hmpps-rest-client';
import { TelemetryClient } from 'applicationinsights';

declare enum PersonSentenceCalculationPermission {
    read = "prisoner:person-sentence-calculation:read",
    edit_adjustments = "prisoner:person-sentence-calculation:adjustments:edit"
}
type PersonSentenceCalculationPermissions = Record<PersonSentenceCalculationPermission, boolean>;

interface SentenceAndOffenceDomainPermissions {
    personSentenceCalculation: PersonSentenceCalculationPermissions;
}
type SentenceAndOffenceDomainPermission = PersonSentenceCalculationPermission;

declare enum PrisonerMoneyPermission {
    read = "prisoner:prisoner-money:read"
}
type PrisonerMoneyPermissions = Record<PrisonerMoneyPermission, boolean>;

declare enum PrisonerAdjudicationsPermission {
    read = "prisoner:prisoner-adjudications:read"
}
type PrisonerAdjudicationsPermissions = Record<PrisonerAdjudicationsPermission, boolean>;

declare enum PrisonerIncentivesPermission {
    read = "prisoner:prisoner-incentives:read"
}
type PrisonerIncentivesPermissions = Record<PrisonerIncentivesPermission, boolean>;

declare enum PersonPrisonCategoryPermission {
    edit = "prisoner:person-prison-category:edit"
}
type PersonPrisonCategoryPermissions = Record<PersonPrisonCategoryPermission, boolean>;

declare enum PrisonerSchedulePermission {
    edit_appointment = "prisoner:appointment:edit",
    edit_activity = "prisoner:activity:edit"
}
type PrisonerSchedulePermissions = Record<PrisonerSchedulePermission, boolean>;

declare enum UseOfForcePermission {
    edit = "prisoner:use-of-force:edit"
}
type UseOfForcePermissions = Record<UseOfForcePermission, boolean>;

declare enum PrisonerAlertsPermission {
    edit = "prisoner:prisoner-alerts:edit"
}
type PrisonerAlertsPermissions = Record<PrisonerAlertsPermission, boolean>;

interface PrisonerSpecificDomainPermissions {
    prisonerMoney: PrisonerMoneyPermissions;
    prisonerAdjudications: PrisonerAdjudicationsPermissions;
    prisonerIncentives: PrisonerIncentivesPermissions;
    personPrisonCategory: PersonPrisonCategoryPermissions;
    prisonerSchedule: PrisonerSchedulePermissions;
    useOfForce: UseOfForcePermissions;
    prisonerAlerts: PrisonerAlertsPermissions;
}
type PrisonerSpecificDomainPermission = PrisonerMoneyPermission | PrisonerAdjudicationsPermission | PrisonerIncentivesPermission | PersonPrisonCategoryPermission | PrisonerSchedulePermission | UseOfForcePermission | PrisonerAlertsPermission;

declare enum PrisonerVisitsAndVisitorsPermission {
    read = "prisoner:prisoner-visits-and-visitors:read"
}
type PrisonerVisitsAndVisitorsPermissions = Record<PrisonerVisitsAndVisitorsPermission, boolean>;

declare enum PrisonerBaseLocationPermission {
    read_location_details = "prisoner:location-details:read",
    read_location_history = "prisoner:location-history:read",
    move_cell = "prisoner:location-cell:edit"
}
type PrisonerBaseLocationPermissions = Record<PrisonerBaseLocationPermission, boolean>;

interface RunningAPrisonDomainPermissions {
    prisonerVisitsAndVisitors: PrisonerVisitsAndVisitorsPermissions;
    prisonerBaseLocation: PrisonerBaseLocationPermissions;
}
type RunningAPrisonDomainPermission = PrisonerVisitsAndVisitorsPermission | PrisonerBaseLocationPermission;

declare enum CaseNotesPermission {
    read = "prisoner:case-notes:read",
    edit = "prisoner:case-notes:edit",
    read_sensitive = "prisoner:case-notes:sensitive:read",
    delete_sensitive = "prisoner:case-notes:sensitive:delete",
    edit_sensitive = "prisoner:case-notes:sensitive:edit"
}
type CaseNotesPermissions = Record<CaseNotesPermission, boolean>;

declare enum CorePersonRecordPermission {
    read_physical_characteristics = "prisoner:physical_characteristics:read",
    edit_physical_characteristics = "prisoner:physical_characteristics:edit",
    read_photo = "prisoner:photo:read",
    edit_photo = "prisoner:photo:edit",
    read_place_of_birth = "prisoner:place-of-birth:read",
    edit_place_of_birth = "prisoner:place-of-birth:edit",
    read_military_history = "prisoner:military-history:read",
    edit_military_history = "prisoner:military-history:edit",
    read_name_and_aliases = "prisoner:name-and-aliases:read",
    edit_name_and_aliases = "prisoner:name-and-aliases:edit",
    read_date_of_birth = "prisoner:date-of-birth:read",
    edit_date_of_birth = "prisoner:date-of-birth:edit",
    read_address = "prisoner:address:read",
    edit_address = "prisoner:address:edit",
    read_nationality = "prisoner:nationality:read",
    edit_nationality = "prisoner:nationality:edit",
    read_identifiers = "prisoner:identifiers:read",
    edit_identifiers = "prisoner:identifiers:edit",
    read_phone_numbers = "prisoner:phone-numbers:read",
    edit_phone_numbers = "prisoner:phone-numbers:edit",
    read_email_addresses = "prisoner:email-addresses:read",
    edit_email_addresses = "prisoner:email-addresses:edit",
    read_distinguishing_marks = "prisoner:distinguishing-marks:read",
    edit_distinguishing_marks = "prisoner:distinguishing-marks:edit"
}
type CorePersonRecordPermissions = Record<CorePersonRecordPermission, boolean>;

declare enum PersonProtectedCharacteristicsPermission {
    read_sexual_orientation = "prisoner:sexual-orientation:read",
    edit_sexual_orientation = "prisoner:sexual-orientation:edit",
    read_religion_and_belief = "prisoner:religion-and-belief:read",
    edit_religion_and_belief = "prisoner:religion-and-belief:edit",
    read_ethnicity = "prisoner:ethnicity:read",
    edit_ethnicity = "prisoner:ethnicity:edit"
}
type PersonProtectedCharacteristicsPermissions = Record<PersonProtectedCharacteristicsPermission, boolean>;

declare enum PersonHealthAndMedicationPermission {
    read_pregnancy = "prisoner:pregnancy:read",
    edit_pregnancy = "prisoner:pregnancy:edit",
    read_diet = "prisoner:diet:read",
    edit_diet = "prisoner:diet:edit",
    read_smoker = "prisoner:smoker:read",
    edit_smoker = "prisoner:smoker:edit"
}
type PersonHealthAndMedicationPermissions = Record<PersonHealthAndMedicationPermission, boolean>;

declare enum PersonalRelationshipsPermission {
    read_number_of_children = "prisoner:number-of-children:read",
    edit_number_of_children = "prisoner:number-of-children:edit",
    read_domestic_status = "prisoner:domestic-status:read",
    edit_domestic_status = "prisoner:domestic-status:edit",
    read_emergency_contacts = "prisoner:emergency-contacts:read",
    edit_emergency_contacts = "prisoner:emergency-contacts:edit",
    read_contacts = "prisoner:contacts:read",
    edit_contacts = "prisoner:contacts:edit",
    edit_contact_restrictions = "prisoner:contact-restrictions:edit",
    edit_contact_visit_approval = "prisoner:contact-visit-approval:edit"
}
type PersonalRelationshipsPermissions = Record<PersonalRelationshipsPermission, boolean>;

interface PersonDomainPermissions {
    caseNotes: CaseNotesPermissions;
    corePersonRecord: CorePersonRecordPermissions;
    personProtectedCharacteristics: PersonProtectedCharacteristicsPermissions;
    personHealthAndMedication: PersonHealthAndMedicationPermissions;
    personalRelationships: PersonalRelationshipsPermissions;
}
type PersonDomainPermission = CaseNotesPermission | CorePersonRecordPermission | PersonProtectedCharacteristicsPermission | PersonHealthAndMedicationPermission | PersonalRelationshipsPermission;

declare enum PathfinderPermission {
    read = "prisoner:pathfinder:read",
    edit = "prisoner:pathfinder:edit"
}
type PathfinderPermissions = Record<PathfinderPermission, boolean>;

declare enum SOCPermission {
    read = "prisoner:soc:read",
    edit = "prisoner:soc:edit"
}
type SOCPermissions = Record<SOCPermission, boolean>;

interface SecurityDomainPermissions {
    pathfinder: PathfinderPermissions;
    soc: SOCPermissions;
}
type SecurityDomainPermission = PathfinderPermission | SOCPermission;

declare enum ProbationDocumentsPermission {
    read = "prisoner:probation-documents:read"
}
type ProbationDocumentsPermissions = Record<ProbationDocumentsPermission, boolean>;

interface ProbationDomainPermissions {
    probationDocuments: ProbationDocumentsPermissions;
}
type ProbationDomainPermission = ProbationDocumentsPermission;

declare enum PersonInterventionsPermission {
    read_csip = "prisoner:csip:read"
}
type PersonInterventionsPermissions = Record<PersonInterventionsPermission, boolean>;

interface InterventionsDomainPermissions {
    personInterventions: PersonInterventionsPermissions;
}
type InterventionsDomainPermission = PersonInterventionsPermission;

declare enum PersonCommunicationNeedsPermission {
    read_language = "prisoner:language:read",
    edit_language = "prisoner:language:edit"
}
type PersonCommunicationNeedsPermissions = Record<PersonCommunicationNeedsPermission, boolean>;

interface PersonPlanAndNeedsDomainPermissions {
    personCommunicationNeeds: PersonCommunicationNeedsPermissions;
}
type PersonPlanAndNeedsDomainPermission = PersonCommunicationNeedsPermission;

declare enum PrisonerBasePermission {
    read = "prisoner:base-record:read"
}
/**
 * These permissions define what a HMPPS user can do with respect to data held about a prisoner.
 */
interface PrisonerPermissions {
    [PrisonerBasePermission.read]: boolean;
    domainGroups: {
        interventions: InterventionsDomainPermissions;
        person: PersonDomainPermissions;
        personPlanAndNeeds: PersonPlanAndNeedsDomainPermissions;
        prisonerSpecific: PrisonerSpecificDomainPermissions;
        probation: ProbationDomainPermissions;
        runningAPrison: RunningAPrisonDomainPermissions;
        security: SecurityDomainPermissions;
        sentenceAndOffence: SentenceAndOffenceDomainPermissions;
    };
}
type PrisonerPermission = PrisonerBasePermission | InterventionsDomainPermission | PersonDomainPermission | PersonPlanAndNeedsDomainPermission | PrisonerSpecificDomainPermission | ProbationDocumentsPermission | RunningAPrisonDomainPermission | SecurityDomainPermission | SentenceAndOffenceDomainPermission;

interface Prisoner {
    prisonerNumber: string;
    prisonId?: string;
    restrictedPatient: boolean;
    supportingPrisonId?: string;
}

interface CaseLoad {
    caseLoadId: string;
    description: string;
    type: string;
    caseloadFunction: string;
    currentlyActive: boolean;
}

declare enum Role {
    ActivityHub = "ROLE_ACTIVITY_HUB",
    AddSensitiveCaseNotes = "ROLE_ADD_SENSITIVE_CASE_NOTES",
    AdjustmentsMaintainer = "ROLE_ADJUSTMENTS_MAINTAINER",
    ApproveCategorisation = "ROLE_APPROVE_CATEGORISATION",
    CategorisationSecurity = "ROLE_CATEGORISATION_SECURITY",
    CellMove = "ROLE_CELL_MOVE",
    ContactsAdministrator = "ROLE_CONTACTS_ADMINISTRATOR",
    ContactsAuthoriser = "ROLE_CONTACTS_AUTHORISER",
    CreateCategorisation = "ROLE_CREATE_CATEGORISATION",
    CreateRecategorisation = "ROLE_CREATE_RECATEGORISATION",
    DeleteSensitiveCaseNotes = "ROLE_DELETE_SENSITIVE_CASE_NOTES",
    DietAndAllergiesEdit = "ROLE_DIET_AND_FOOD_ALLERGIES_EDIT",
    GlobalSearch = "ROLE_GLOBAL_SEARCH",
    InactiveBookings = "ROLE_INACTIVE_BOOKINGS",
    PathfinderApproval = "ROLE_PF_APPROVAL",
    PathfinderHQ = "ROLE_PF_HQ",
    PathfinderLocalReader = "ROLE_PF_LOCAL_READER",
    PathfinderNationalReader = "ROLE_PF_NATIONAL_READER",
    PathfinderPolice = "ROLE_PF_POLICE",
    PathfinderPsychologist = "ROLE_PF_PSYCHOLOGIST",
    PathfinderStdPrison = "ROLE_PF_STD_PRISON",
    PathfinderStdProbation = "ROLE_PF_STD_PROBATION",
    PathfinderUser = "ROLE_PF_USER",
    PomUser = "ROLE_POM",
    PrisonerProfilePhotoUpload = "ROLE_PRISONER_PROFILE_PHOTO_UPLOAD",
    PrisonerProfileSensitiveEdit = "ROLE_PRISONER_PROFILE_SENSITIVE_RW",
    ReceptionUser = "ROLE_PRISON_RECEPTION",
    ReleaseDatesCalculator = "ROLE_RELEASE_DATES_CALCULATOR",
    SocCommunity = "ROLE_SOC_COMMUNITY",
    SocCustody = "ROLE_SOC_CUSTODY",
    SocDataAnalyst = "ROLE_SOC_DATA_ANALYST",
    SocDataManager = "ROLE_SOC_DATA_MANAGER",
    UpdateAlert = "ROLE_UPDATE_ALERT",
    ViewProbationDocuments = "ROLE_VIEW_PROBATION_DOCUMENTS",
    ViewSensitiveCaseNotes = "ROLE_VIEW_SENSITIVE_CASE_NOTES"
}

type AuthSource = 'nomis' | 'delius' | 'external' | 'azuread';
/**
 * These are the details that all user types share.
 */
interface BaseUser {
    authSource: AuthSource;
    username: string;
    userId: string;
    name: string;
    displayName: string;
    userRoles: Role[];
    token?: string;
    backLink?: string;
}
/**
 * Prison users are those that have a user account in NOMIS.
 * HMPPS Auth automatically grants these users a `ROLE_PRISON` role.
 * Prison users have an additional numerical staffId. The userId is
 * a stringified version of the staffId. Some teams may need to separately
 * retrieve the user case load (which prisons that a prison user has access
 * to) and store it here, an example can be found in `hmpps-prisoner-profile`.
 */
interface PrisonUser extends BaseUser {
    authSource: 'nomis';
    staffId: number;
    activeCaseLoadId: string;
    caseLoads: CaseLoad[];
    keyWorkerAtPrisons: Record<string, boolean>;
}
/**
 * Probation users are those that have a user account in nDelius.
 * HMPPS Auth automatically grants these users a `ROLE_PROBATION` role.
 */
interface ProbationUser extends BaseUser {
    authSource: 'delius';
}
/**
 * External users are those that have a user account in our External Users
 * database. These accounts are created for users that need access to HMPPS
 * services but have neither NOMIS nor nDelius access.
 */
interface ExternalUser extends BaseUser {
    authSource: 'external';
}
/**
 * AzureAD users are those that have a justice.gov.uk email address and
 * an account in MoJ's Azure AD (now called Entra ID) tenant. HMPPS Auth
 * will normally check to see if there is a Prison/Probation/External
 * user with the same email address and request that the user to pick one
 * to use to access the service, however if there is no match, it is
 * possible that a user of this type could attempt to access the service,
 * and would have no user roles associated.
 */
interface AzureADUser extends BaseUser {
    authSource: 'azuread';
}
type HmppsUser = PrisonUser | ProbationUser | ExternalUser | AzureADUser;

declare enum PermissionCheckStatus {
    NOT_PERMITTED = "NOT_PERMITTED",// Generic not permitted status - default
    NOT_IN_CASELOAD = "NOT_IN_CASELOAD",
    NOT_ACTIVE_CASELOAD = "NOT_ACTIVE_CASELOAD",
    RESTRICTED_PATIENT = "RESTRICTED_PATIENT",
    PRISONER_IS_RELEASED = "PRISONER_IS_RELEASED",
    PRISONER_IS_TRANSFERRING = "PRISONER_IS_TRANSFERRING",
    ROLE_NOT_PRESENT = "ROLE_NOT_PRESENT",
    NOT_PRISON_USER = "NOT_PRISON_USER",
    OK = "OK"
}

declare class PermissionsLogger {
    private readonly logger;
    private readonly telemetryClient?;
    constructor(logger: Logger | Console, telemetryClient?: TelemetryClient | undefined);
    logPermissionCheckStatus(user: HmppsUser, prisoner: Prisoner, permission: PrisonerPermission, permissionCheckStatus: PermissionCheckStatus): void;
}

declare class PermissionsService {
    private readonly prisonerSearchClient;
    readonly permissionsLogger: PermissionsLogger;
    static create({ prisonerSearchConfig, authenticationClient, logger, telemetryClient, }: {
        prisonerSearchConfig: ApiConfig;
        authenticationClient: AuthenticationClient;
        logger?: Logger | typeof console;
        telemetryClient?: TelemetryClient;
    }): PermissionsService;
    private constructor();
    getPrisonerPermissions({ user, prisoner, requestDependentOn, }: {
        user: HmppsUser;
        prisoner: Prisoner;
        requestDependentOn: PrisonerPermission[];
    }): PrisonerPermissions;
    getPrisonerDetails(prisonerNumber: string): Promise<Prisoner>;
}

declare function prisonerPermissionsGuard(permissionsService: PermissionsService, options: {
    requestDependentOn: PrisonerPermission[];
    getPrisonerNumberFunction?: (req: Request) => string | undefined;
}): (req: Request, res: Response, next: NextFunction) => Promise<void>;

interface NunjucksEnvironment {
    addGlobal: (name: string, value: unknown) => NunjucksEnvironment;
}
declare function setupNunjucksPermissions(njkEnv: NunjucksEnvironment): void;

type Join<K, P> = K extends string | number ? (P extends string | number ? `${K}.${P}` : never) : never;
type Path<T> = T extends object ? {
    [K in keyof T]-?: K extends string | number ? `${K}` | Join<K, Path<T[K]>> : never;
}[keyof T] : '';

declare const prisonerPermissionPaths: Record<PrisonerPermission, Path<PrisonerPermissions>>;

declare function isGranted(permission: PrisonerPermission, permissions: PrisonerPermissions | undefined): boolean;

declare const interventionsDomainPermissionPaths: Record<InterventionsDomainPermission, Path<PrisonerPermissions>>;

declare const personDomainPermissionPaths: Record<PersonDomainPermission, Path<PrisonerPermissions>>;

declare const personPlanAndNeedsDomainPermissionPaths: Record<PersonPlanAndNeedsDomainPermission, Path<PrisonerPermissions>>;

declare const prisonerSpecificDomainPermissionPaths: Record<PrisonerSpecificDomainPermission, Path<PrisonerPermissions>>;

declare const probationDomainPermissionPaths: Record<ProbationDomainPermission, Path<PrisonerPermissions>>;

declare const runningAPrisonDomainPermissionPaths: Record<RunningAPrisonDomainPermission, Path<PrisonerPermissions>>;

declare const securityDomainPermissionPaths: Record<SecurityDomainPermission, Path<PrisonerPermissions>>;

declare const sentenceAndOffenceDomainPermissionPaths: Record<SentenceAndOffenceDomainPermission, Path<PrisonerPermissions>>;

declare const personInterventionsPermissionPaths: Record<PersonInterventionsPermission, Path<PrisonerPermissions>>;

declare const corePersonRecordPermissionPaths: Record<CorePersonRecordPermission, Path<PrisonerPermissions>>;

declare const caseNotesPermissionPaths: Record<CaseNotesPermission, Path<PrisonerPermissions>>;

declare const personHealthAndMedicationPermissionPaths: Record<PersonHealthAndMedicationPermission, Path<PrisonerPermissions>>;

declare const personProtectedCharacteristicsPermissionPaths: Record<PersonProtectedCharacteristicsPermission, Path<PrisonerPermissions>>;

declare const personalRelationshipsPermissionPaths: Record<PersonalRelationshipsPermission, Path<PrisonerPermissions>>;

declare const personPrisonCategoryPermissionPaths: Record<PersonPrisonCategoryPermission, Path<PrisonerPermissions>>;

declare const personCommunicationNeedsPermissionPaths: Record<PersonCommunicationNeedsPermission, Path<PrisonerPermissions>>;

declare const prisonerAdjudicationsPermissionPaths: Record<PrisonerAdjudicationsPermission, Path<PrisonerPermissions>>;

declare const prisonerAlertsPermissionPaths: Record<PrisonerAlertsPermission, Path<PrisonerPermissions>>;

declare const prisonerIncentivesPermissionPaths: Record<PrisonerIncentivesPermission, Path<PrisonerPermissions>>;

declare const prisonerMoneyPermissionPaths: Record<PrisonerMoneyPermission, Path<PrisonerPermissions>>;

declare const prisonerSchedulePermissionPaths: Record<PrisonerSchedulePermission, Path<PrisonerPermissions>>;

declare const useOfForcePermissionPaths: Record<UseOfForcePermission, Path<PrisonerPermissions>>;

declare const probationDocumentsPermissionPaths: Record<ProbationDocumentsPermission, Path<PrisonerPermissions>>;

declare const prisonerBaseLocationPermissionPaths: Record<PrisonerBaseLocationPermission, Path<PrisonerPermissions>>;

declare const prisonerVisitsAndVisitorsPermissionPaths: Record<PrisonerVisitsAndVisitorsPermission, Path<PrisonerPermissions>>;

declare const pathfinderPermissionPaths: Record<PathfinderPermission, Path<PrisonerPermissions>>;

declare const socPermissionPaths: Record<SOCPermission, Path<PrisonerPermissions>>;

declare const personSentenceCalculationPermissionPaths: Record<PersonSentenceCalculationPermission, Path<PrisonerPermissions>>;

export { CaseNotesPermission, CorePersonRecordPermission, PathfinderPermission, PermissionsService, PersonCommunicationNeedsPermission, PersonHealthAndMedicationPermission, PersonInterventionsPermission, PersonPrisonCategoryPermission, PersonProtectedCharacteristicsPermission, PersonSentenceCalculationPermission, PersonalRelationshipsPermission, PrisonerAdjudicationsPermission, PrisonerAlertsPermission, PrisonerBaseLocationPermission, PrisonerBasePermission, PrisonerIncentivesPermission, PrisonerMoneyPermission, PrisonerSchedulePermission, PrisonerVisitsAndVisitorsPermission, ProbationDocumentsPermission, SOCPermission, UseOfForcePermission, caseNotesPermissionPaths, corePersonRecordPermissionPaths, interventionsDomainPermissionPaths, isGranted, pathfinderPermissionPaths, personCommunicationNeedsPermissionPaths, personDomainPermissionPaths, personHealthAndMedicationPermissionPaths, personInterventionsPermissionPaths, personPlanAndNeedsDomainPermissionPaths, personPrisonCategoryPermissionPaths, personProtectedCharacteristicsPermissionPaths, personSentenceCalculationPermissionPaths, personalRelationshipsPermissionPaths, prisonerAdjudicationsPermissionPaths, prisonerAlertsPermissionPaths, prisonerBaseLocationPermissionPaths, prisonerIncentivesPermissionPaths, prisonerMoneyPermissionPaths, prisonerPermissionPaths, prisonerPermissionsGuard, prisonerSchedulePermissionPaths, prisonerSpecificDomainPermissionPaths, prisonerVisitsAndVisitorsPermissionPaths, probationDocumentsPermissionPaths, probationDomainPermissionPaths, runningAPrisonDomainPermissionPaths, securityDomainPermissionPaths, sentenceAndOffenceDomainPermissionPaths, setupNunjucksPermissions, socPermissionPaths, useOfForcePermissionPaths };
export type { CaseNotesPermissions, CorePersonRecordPermissions, InterventionsDomainPermission, InterventionsDomainPermissions, PathfinderPermissions, PersonCommunicationNeedsPermissions, PersonDomainPermission, PersonDomainPermissions, PersonHealthAndMedicationPermissions, PersonInterventionsPermissions, PersonPlanAndNeedsDomainPermission, PersonPlanAndNeedsDomainPermissions, PersonPrisonCategoryPermissions, PersonProtectedCharacteristicsPermissions, PersonSentenceCalculationPermissions, PersonalRelationshipsPermissions, PrisonerAdjudicationsPermissions, PrisonerAlertsPermissions, PrisonerBaseLocationPermissions, PrisonerIncentivesPermissions, PrisonerMoneyPermissions, PrisonerPermission, PrisonerPermissions, PrisonerSchedulePermissions, PrisonerSpecificDomainPermission, PrisonerSpecificDomainPermissions, PrisonerVisitsAndVisitorsPermissions, ProbationDocumentsPermissions, ProbationDomainPermission, ProbationDomainPermissions, RunningAPrisonDomainPermission, RunningAPrisonDomainPermissions, SOCPermissions, SecurityDomainPermission, SecurityDomainPermissions, SentenceAndOffenceDomainPermission, SentenceAndOffenceDomainPermissions, UseOfForcePermissions };
