const electron = require('electron')
const os = require('os')
const fs = require('fs')
const Path = require('path')
const sharp = require('sharp')
const LibRaw = require('node-libraw')

const remote = electron.remote
const dialog = remote.dialog

class Filesystem {
  constructor(filetypes) {
    this.filetypes = filetypes
  }

  createThumbnail(path, options, callback) {
    const {width, height} = options

    if (this.filetypes.isRAW(path)) {
      LibRaw.extractThumb(path).then((output) => {
        sharp(output)
          .resize(width, height, {interpolator: 'bilinear'})
          .rotate()
          .png()
          .toBuffer(callback)
      })
    } else {
      sharp(path)
        .resize(width, height, {interpolator: 'bilinear'})
        .rotate()
        .png()
        .toBuffer(callback)
    }
  }

  remove(path, callback) {
    fs.unlink(path, callback)
  }

  read(path, success, error) {
    if (this.filetypes.isRAW(path)) {
      console.time('process raw')
      LibRaw.extract(path, (err, data, width, height) => {
        console.timeEnd('process raw')
        if (err) return error(err)
        success(data, width, height)
      })
    } else {
      fs.readFile(path, (err, data) => {
        if (err) return error(err)
        success(data);
      });
    }
  }

  open(options, callback) {
    dialog.showOpenDialog({
      properties: ['openFile', 'multiSelections']
    }, (paths = []) => {
      let files = []
      paths.forEach((path) => {
        let stats = fs.statSync(path)
        if (stats.isDirectory()) {
          fs.readdirSync(path)
            .filter((file) => this.filetypes.isSupported(file))
            .forEach((file) => {
              let fullPath = Path.join(path, file)
              let stats = fs.statSync(fullPath)
              files.push({
                directory: path,
                path: fullPath,
                name: file,
                size: stats.size
              })
          })
        } else if (this.filetypes.isSupported(path)) {
          files.push({
            directory: Path.dirname(path),
            path: path,
            name: Path.basename(path),
            size: stats.size
          })
        }
      })
      callback(files)
    })
  }

  choosePath(options, callback) {
    if (options.directory) {
      dialog.showOpenDialog({
        properties: ['openDirectory']
      }, function (path) {
        callback({path: path[0], directory: options.directory})
      })

    } else {
      dialog.showSaveDialog({
        defaultPath: '~/' + options.filename
      }, function (path) {
        callback({path: path, directory: options.directory})
      })
    }
  }

  save(blob, options = {}) {
    const {success, error, cancel, filename, filetype, entry} = options

    if (!options.entry.path) {
      cancel()
      return
    }

    const filepath = entry.directory ? entry.path + "/" + filename : entry.path;

    const fileReader = new FileReader();
    fileReader.onload = function () {
      fs.writeFile(filepath, Buffer(new Uint8Array(this.result)), filetype, function (err) {
        if(err) {
          error(err)
        } else {
          success()
        }
      });
    };
    fileReader.readAsArrayBuffer(blob);

  }
}

window.Electron = electron
window.Filesystem = Filesystem