
const path = require('path');
const { pick } = require('lodash');
const actions = require('./actions');
const File = require('./file');
const { TYPE } = require('./resolve');
const getImageDimensions = require('./lib/dimensions');
const getVideoDimensions = require('get-video-dimensions');

const WIDTHS = [ 2048, 1024, 768, 576, 300, 100 ];

module.exports = exports = class Asset extends File {

  constructor (filepath) {
    super(filepath);

    this.serializable.push(
      'dimensions',
      'sizes',
    );
  }

  load () {
    switch (this.type) {
    case TYPE.VIDEO: return this.loadVideo();
    case TYPE.IMAGE: return this.loadImage();
    default:
      return this.loadOther();
    }
  }

  async loadImage () {

    const { width, height } = await getImageDimensions(this.input);

    const ratioH = Math.round((height / width) * 100);
    const ratioW = Math.round((width / height) * 100);
    let orientation = 'wide';
    if (ratioH > 100) {
      orientation = 'tall';
    } else if (ratioH === 100) {
      orientation = 'square';
    }

    this.dimensions = {
      width,
      height,
      ratioH,
      ratioW,
      orientation,
    };

    this.sizes = [ {
      url: this.url,
      width,
      height,
    } ];

    if (this.preprocessed || this.ext === '.svg') {
      this._tasks = [ {
        output: this.out,
        input: this.input,
        action: actions.copy,
        nocache: true,
      } ];
      return;
    }

    this._tasks = [
      {
        output: this.out,
        input: this.input,
        width,
        height,
        format: 'jpeg',
        action: actions.image,
      },
    ];

    for (const w of WIDTHS) {
      if (w > width) continue;
      const name = `${this.name}.${w}w${this.ext}`;
      this.sizes.push({
        url:    path.join(this.dir,  name),
        width:  w,
        height: Math.ceil((w / width) * height),
      });
      this._tasks.push({
        output: path.join(this.base, name),
        input: this.input,
        width: w,
        format: 'jpeg',
        fill: 'contain',
        quality: 85,
        action: actions.image,
      });
    }

    this.sizes.reverse();

    return this;
  }

  async loadVideo () {
    const { width, height } = await getVideoDimensions(this.input);

    const ratioH = Math.round((height / width) * 100);
    const ratioW = Math.round((width / height) * 100);
    let orientation = 'wide';
    if (ratioH > 100) {
      orientation = 'tall';
    } else if (ratioH === 100) {
      orientation = 'square';
    }

    this.dimensions = {
      width,
      height,
      ratioH,
      ratioW,
      orientation,
    };

    this.sizes = [ {
      url:    path.join(this.dir,  this.basename),
      width,
      height,
    } ];

    this._tasks = [
      {
        output: this.out,
        input: this.input,
        action: actions.copy,
        nocache: true,
      },
    ];

    return this;
  }

  get webready () {
    const { type, name, url, sizes } = this;
    return {
      type,
      name,
      url,
      sizes: sizes.map((s) => pick(s, [ 'url', 'width', 'height' ])),
    };
  }

  tasks () {
    return this._tasks;
  }

};
