import loggerFactory from '~/utils/logger';

// disable no-return-await for model functions
/* eslint-disable no-return-await */

// eslint-disable-next-line no-unused-vars
const path = require('path');

const mongoose = require('mongoose');
const uniqueValidator = require('mongoose-unique-validator');
const mongoosePaginate = require('mongoose-paginate-v2');
const { addSeconds } = require('date-fns');

// eslint-disable-next-line no-unused-vars
const logger = loggerFactory('growi:models:attachment');

const ObjectId = mongoose.Schema.Types.ObjectId;

module.exports = function(crowi) {
  function generateFileHash(fileName) {
    const hash = require('crypto').createHash('md5');
    hash.update(`${fileName}_${Date.now()}`);

    return hash.digest('hex');
  }

  const attachmentSchema = new mongoose.Schema({
    page: { type: ObjectId, ref: 'Page', index: true },
    creator: { type: ObjectId, ref: 'User', index: true },
    filePath: { type: String }, // DEPRECATED: remains for backward compatibility for v3.3.x or below
    fileName: { type: String, required: true, unique: true },
    originalName: { type: String },
    fileFormat: { type: String, required: true },
    fileSize: { type: Number, default: 0 },
    createdAt: { type: Date, default: Date.now },
    temporaryUrlCached: { type: String },
    temporaryUrlExpiredAt: { type: Date },
  });
  attachmentSchema.plugin(uniqueValidator);
  attachmentSchema.plugin(mongoosePaginate);

  attachmentSchema.virtual('filePathProxied').get(function() {
    return `/attachment/${this._id}`;
  });

  attachmentSchema.virtual('downloadPathProxied').get(function() {
    return `/download/${this._id}`;
  });

  attachmentSchema.set('toObject', { virtuals: true });
  attachmentSchema.set('toJSON', { virtuals: true });


  attachmentSchema.statics.createWithoutSave = function(pageId, user, fileStream, originalName, fileFormat, fileSize) {
    const Attachment = this;

    const extname = path.extname(originalName);
    let fileName = generateFileHash(originalName);
    if (extname.length > 1) { // ignore if empty or '.' only
      fileName = `${fileName}${extname}`;
    }

    const attachment = new Attachment();
    attachment.page = pageId;
    attachment.creator = user._id;
    attachment.originalName = originalName;
    attachment.fileName = fileName;
    attachment.fileFormat = fileFormat;
    attachment.fileSize = fileSize;
    attachment.createdAt = Date.now();

    return attachment;
  };


  attachmentSchema.methods.getValidTemporaryUrl = function() {
    if (this.temporaryUrlExpiredAt == null) {
      return null;
    }
    // return null when expired url
    if (this.temporaryUrlExpiredAt.getTime() < new Date().getTime()) {
      return null;
    }
    return this.temporaryUrlCached;
  };

  attachmentSchema.methods.cashTemporaryUrlByProvideSec = function(temporaryUrl, provideSec) {
    if (temporaryUrl == null) {
      throw new Error('url is required.');
    }
    this.temporaryUrlCached = temporaryUrl;
    this.temporaryUrlExpiredAt = addSeconds(new Date(), provideSec);

    return this.save();
  };

  return mongoose.model('Attachment', attachmentSchema);
};
