const { Controller } = require('libflitter')

class VaultController extends Controller {
    static get services() {
        return [...super.services, 'models']
    }

    async get_vaults(req, res, next) {
        const Policy = this.models.get('iam:Policy')
        const Vault = this.models.get('vault:Vault')

        await Vault.for_user(req.user)

        const vaults = await Vault.find({ active: true })
        console.log('found vaults', vaults)

        const accessible = []
        for ( const vault of vaults ) {
            if ( await Policy.check_user_access(req.user, vault.id, 'view') ) {
                accessible.push(await vault.to_api())
            }
        }

        return res.api(accessible)
    }

    async get_vault(req, res, next) {
        const Policy = this.models.get('iam:Policy')
        const Vault = this.models.get('vault:Vault')

        const vault = await Vault.findById(req.params.id)
        if ( !vault?.active ) {
            return res.status(404)
                .message(req.T('api.vault_not_found'))
                .api()
        }

        if ( !(await Policy.check_user_access(req.user, vault.id, 'view')) ) {
            return res.status(401)
                .message(req.T('api.insufficient_permissions'))
                .api()
        }

        return res.api(await vault.to_api())
    }

    async create_vault(req, res, next) {
        const Policy = this.models.get('iam:Policy')
        const Vault = this.models.get('vault:Vault')

        if ( !req.body.name ) {
            return res.status(400)
                .message(`${req.T('api.missing_field')} name`)
                .api()
        }

        const vault = new Vault({
            name: req.body.name
        })

        await vault.save()
        await vault.grant_default(req.user)

        return res.api(await vault.to_api())
    }

    async update_vault(req, res, next) {
        const Policy = this.models.get('iam:Policy')
        const Vault = this.models.get('vault:Vault')

        if ( !req.body.name ) {
            return res.status(400)
                .message(`${req.T('api.missing_field')} name`)
                .api()
        }

        const vault = await Vault.findById(req.params.id)
        if ( !vault?.active ) {
            return res.status(404)
                .message(req.T('api.vault_not_found'))
                .api()
        }

        if ( !(await Policy.check_user_access(req.user, vault.id, 'update')) ) {
            return res.status(401)
                .message(req.T('api.insufficient_permissions'))
                .api()
        }

        vault.name = req.body.name
        await vault.save()
        return res.api(await vault.to_api())
    }

    async delete_vault(req, res, next) {
        const Policy = this.models.get('iam:Policy')
        const Vault = this.models.get('vault:Vault')

        const vault = await Vault.findById(req.params.id)
        if ( !vault?.active ) {
            return res.status(404)
                .message(req.T('api.vault_not_found'))
                .api()
        }

        if ( !(await Policy.check_user_access(req.user, vault.id, 'delete')) ) {
            return res.status(401)
                .message(req.T('api.insufficient_permissions'))
                .api()
        }

        vault.active = false
        await vault.save()

        const policies = await Policy.find({
            active: true,
            target_type: 'vault',
            target_id: vault.id,
        })

        for ( const policy of policies ) {
            policy.active = false
            await policy.save()
        }

        return res.api()
    }
}

module.exports = exports = VaultController
