import CRUDBase from '../CRUDBase.js'
import { session } from '../../service/Session.service.js'

class PolicyResource extends CRUDBase {
    constructor() {
        super()

        this.endpoint = '/api/v1/iam/policy'
        this.required_fields = ['entity_id', 'entity_type', 'target_id', 'target_type', 'access_type']
        this.permission_base = 'v1:iam:policy'

        this.item = 'IAM Policy'
        this.plural = 'IAM Policies'

        this.listing_definition = {
            display: `
        Identity & Access Management (IAM) policies give you fine grained control over which ${session.get('app.name')} users and groups are allowed to access which applications.
        <br><br>
        An IAM policy has three parts. First, is the subject. The subject is who the policy applies to and is either a user or a group. The second part is the access type. This is either an allowance or a denial. That is, the policy either grants a subject access to a resource, or explicitly denies them access. The final part of the policy is the target. This is the application that the subject is being granted or denied access to.
        <br><br> 
        Note that IAM policies can be overlapping. So, ${session.get('app.name')}'s policy engine follows a few basic rules when deciding what policies take precedence:
            <br><br>
            <ol>
                <li>User policy takes precedence over group policy.</li>
                <li>Denials take precedence over approvals.</li>
                <li>Denials by default.</li>
            </ol>
        This means, for example, that if a user's group is allowed access, but a user is denied access, the user will be denied access. Likewise, if there are two policies for a subject, one granting them access and one denying them access, the denial will take precedence.
        `,
            columns: [
                {
                    name: 'Subject',
                    field: 'entity_display',
                },
                {
                    name: 'Access Type',
                    field: 'access_type',
                    renderer: access_type => access_type === 'deny' ? '...is denied access to...' : '...is granted access to...',
                },
                {
                    name: 'Target',
                    field: 'target_display',
                },
                {
                    name: 'Permission',
                    field: 'permission',
                    renderer: permission => permission || '-',
                },
            ],
            actions: [
                {
                    type: 'resource',
                    position: 'main',
                    action: 'insert',
                    text: 'Create New',
                    color: 'success',
                },
                {
                    type: 'resource',
                    position: 'row',
                    action: 'update',
                    icon: 'fa fa-edit',
                    color: 'primary',
                },
                {
                    type: 'resource',
                    position: 'row',
                    action: 'delete',
                    icon: 'fa fa-times',
                    color: 'danger',
                    confirm: true,
                },
            ],
        }

        this.form_definition = {
            fields: [
                {
                    name: 'Subject Type',
                    field: 'entity_type',
                    required: true,
                    type: 'select',
                    options: [
                        {display: 'User', value: 'user'},
                        {display: 'Group', value: 'group'},
                    ],
                },
                {
                    name: 'Subject',
                    field: 'entity_id',
                    required: true,
                    type: 'select.dynamic',
                    options: {
                        resource: 'auth/User',
                        display: user => `User: ${user.last_name}, ${user.first_name} (${user.uid})`,
                        value: 'id',
                    },
                    if: (form_data) => form_data.entity_type === 'user',
                },
                {
                    name: 'Subject',
                    field: 'entity_id',
                    required: true,
                    type: 'select.dynamic',
                    options: {
                        resource: 'auth/Group',
                        display: group => `Group: ${group.name} (${group.user_ids.length} users)`,
                        value: 'id',
                    },
                    if: (form_data) => form_data.entity_type === 'group',
                },
                {
                    name: 'Access Type',
                    field: 'access_type',
                    required: true,
                    type: 'select',
                    options: [
                        {display: '...is granted access to...', value: 'allow'},
                        {display: '...is denied access to...', value: 'deny'},
                    ],
                },
                {
                    name: 'Target Type',
                    field: 'target_type',
                    required: true,
                    type: 'select',
                    options: [
                        {display: 'Application', value: 'application'},
                        {display: 'API Scope', value: 'api_scope'},
                        {display: 'Computer', value: 'machine'},
                        {display: 'Computer Group', value: 'machine_group'},
                        {display: 'Vault', value: 'vault'},
                    ],
                },
                {
                    name: 'Target',
                    field: 'target_id',
                    required: true,
                    type: 'select.dynamic',
                    options: {
                        resource: 'App',
                        display: 'name',
                        value: 'id',
                    },
                    if: (form_data) => form_data.target_type === 'application'
                },
                {
                    name: 'Target',
                    field: 'target_id',
                    required: true,
                    type: 'select.dynamic',
                    options: {
                        resource: 'reflect/Scope',
                        display: 'scope',
                        value: 'scope',
                    },
                    if: (form_data) => form_data.target_type === 'api_scope'
                },
                {
                    name: 'Target',
                    field: 'target_id',
                    required: true,
                    type: 'select.dynamic',
                    options: {
                        resource: 'ldap/Machine',
                        display: machine => `${machine.name}${machine.host_name ? ' (' + machine.host_name + ')' : ''}`,
                        value: 'id',
                    },
                    if: (form_data) => form_data.target_type === 'machine'
                },
                {
                    name: 'Target',
                    field: 'target_id',
                    required: true,
                    type: 'select.dynamic',
                    options: {
                        resource: 'ldap/MachineGroup',
                        display: group => `${group.name} (${(group.machine_ids || []).length} computers)`,
                        value: 'id',
                    },
                    if: (form_data) => form_data.target_type === 'machine_group'
                },
                {
                    name: 'Target',
                    field: 'target_id',
                    required: true,
                    type: 'select.dynamic',
                    options: {
                        resource: 'vault/Vault',
                        display: 'name',
                        value: 'id',
                    },
                    if: (form_data) => form_data.target_type === 'vault'
                },
                {
                    name: 'Permission',
                    field: 'permission',
                    required: false,
                    type: 'select.dynamic',
                    options: {
                        resource: 'iam/Permission',
                        display: 'permission',
                        value: 'permission',
                        other_params: {
                            target_type: 'application',
                            include_unset: true,
                        },
                    },
                    if: (form_data, opts) => form_data.target_type === 'application' && opts?.length
                },
                {
                    name: 'Permission',
                    field: 'permission',
                    required: false,
                    type: 'select.dynamic',
                    options: {
                        resource: 'iam/Permission',
                        display: 'permission',
                        value: 'permission',
                        other_params: {
                            target_type: 'api_scope',
                            include_unset: true,
                        },
                    },
                    if: (form_data, opts) => form_data.target_type === 'api_scope' && opts?.length
                },
                {
                    name: 'Permission',
                    field: 'permission',
                    required: false,
                    type: 'select.dynamic',
                    options: {
                        resource: 'iam/Permission',
                        display: 'permission',
                        value: 'permission',
                        other_params: {
                            target_type: 'machine',
                            include_unset: true,
                        },
                    },
                    if: (form_data, opts) => form_data.target_type === 'machine' && opts?.length
                },
                {
                    name: 'Permission',
                    field: 'permission',
                    required: false,
                    type: 'select.dynamic',
                    options: {
                        resource: 'iam/Permission',
                        display: 'permission',
                        value: 'permission',
                        other_params: {
                            target_type: 'machine_group',
                            include_unset: true,
                        },
                    },
                    if: (form_data, opts) => form_data.target_type === 'machine_group' && opts?.length
                },
                {
                    name: 'Permission',
                    field: 'permission',
                    required: false,
                    type: 'select.dynamic',
                    options: {
                        resource: 'iam/Permission',
                        display: 'permission',
                        value: 'permission',
                        other_params: {
                            target_type: 'vault',
                            include_unset: true,
                        },
                    },
                    if: (form_data, opts) => form_data.target_type === 'vault' && opts?.length
                },
            ],
            /*handlers: {
                insert: {
                    action: 'back',
                },
                update: {
                    action: 'back',
                },
            },*/
        }
    }
}

const iam_policy = new PolicyResource()
export { iam_policy }
