const UserError = require('vn-loopback/util/user-error');
const fs = require('fs-extra');
const path = require('path');

module.exports = Self => {
    require('../methods/dms/downloadFile')(Self);
    require('../methods/dms/uploadFile')(Self);
    require('../methods/dms/removeFile')(Self);
    require('../methods/dms/updateFile')(Self);
    require('../methods/dms/deleteTrashFiles')(Self);

    Self.checkRole = async function(ctx, id) {
        const models = Self.app.models;
        const dms = await Self.findById(id);

        return await models.DmsType.hasReadRole(ctx, dms.dmsTypeFk);
    };

    Self.getFile = async function(id) {
        const models = Self.app.models;
        const DmsContainer = models.DmsContainer;
        const dms = await Self.findById(id);
        const pathHash = DmsContainer.getHash(dms.id);
        try {
            await DmsContainer.getFile(pathHash, dms.file);
        } catch (e) {
            if (e.code != 'ENOENT')
                throw e;

            const error = new UserError(`File doesn't exists`);
            error.statusCode = 404;

            throw error;
        }

        const stream = DmsContainer.downloadStream(pathHash, dms.file);

        return [stream, dms.contentType, `filename="${dms.file}"`];
    };

    Self.getPath = async function(dms) {
        const models = Self.app.models;
        const pathHash = await models.DmsContainer.getHash(dms.id);
        const dmsContainer = await models.DmsContainer.container(pathHash);
        const dstFile = path.join(dmsContainer.client.root, pathHash, dms.file);
        return dstFile;
    };

    Self.createWithExtension = async function(data, extension, options) {
        const newDms = await Self.create(data, options);
        return newDms.updateAttribute('file', `${newDms.id}.${extension}`, options);
    };

    Self.createFromFile = async function(data, extension, srcFile, options) {
        const dms = await Self.createWithExtension(data, extension, options);
        const dstFile = await Self.getPath(dms);
        await fs.move(srcFile, dstFile, {overwrite: true});
        return dms;
    };

    Self.createFromStream = async function(data, extension, stream, options) {
        const dms = await Self.createWithExtension(data, extension, options);
        const dstFile = await Self.getPath(dms);
        const writeStream = await fs.createWriteStream(dstFile);
        await stream.pipe(writeStream);
        return dms;
    };
};