hunk.code_window:  * @summary writes the source to the destinations and valiates the writes
    * @param {SourceDestination} source - source
    * @param {SourceDestination[]} destinations - destinations
    * @param {Boolean} verify - whether to validate the writes or not
    * @param {Function} onProgress - function to call on progress
    * @param {Function} onFail - function to call on fail
    * @returns {Promise<{ bytesWritten, devices, errors} >}
    *
  
hunk.labels: keep keep keep add keep keep keep keep
hunk.after_edit:  * @param {Boolean} trim - whether to trim ext partitions before writing
  
hunk.file_path: lib/gui/modules/child-writer.js
hunk.type: add
file: /*
   * Copyright 2017 resin.io
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *    http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  'use strict'
  
  const Bluebird = require('bluebird')
  const fs = require('fs')
  const path = require('path')
  
  /**
   * @summary Number of spaces to indent JSON output with
   * @type {Number}
   * @constant
   */
  const JSON_INDENT = 2
  
  /**
   * @summary Userdata directory path
   * @description
   * Defaults to the following:
   * - `%APPDATA%/etcher` on Windows
   * - `$XDG_CONFIG_HOME/etcher` or `~/.config/etcher` on Linux
   * - `~/Library/Application Support/etcher` on macOS
   * See https://electronjs.org/docs/api/app#appgetpathname
   * @constant
   * @type {String}
   */
  const USER_DATA_DIR = (() => {
    // NOTE: The ternary is due to this module being loaded both,
    // Electron's main process and renderer process
    const electron = require('electron')
    return electron.app
      ? electron.app.getPath('userData')
      : electron.remote.app.getPath('userData')
  })()
  
  /**
   * @summary Configuration file path
   * @type {String}
   * @constant
   */
  const CONFIG_PATH = path.join(USER_DATA_DIR, 'config.json')
  
  /**
   * @summary Read a local config.json file
   * @function
   * @private
   *
   * @param {String} filename - file path
   * @fulfil {Object} - settings
   * @returns {Promise}
   *
   * @example
   * readConfigFile('config.json').then((settings) => {
   *   console.log(settings)
   * })
   */
  const readConfigFile = (filename) => {
    return new Bluebird((resolve, reject) => {
      fs.readFile(filename, { encoding: 'utf8' }, (error, contents) => {
        let data = {}
        if (error) {
          if (error.code === 'ENOENT') {
            resolve(data)
          } else {
            reject(error)
          }
        } else {
          try {
            data = JSON.parse(contents)
          } catch (parseError) {
            console.error(parseError)
          }
          resolve(data)
        }
      })
    })
  }
  
  /**
   * @summary Write to the local configuration file
   * @function
   * @private
   *
   * @param {String} filename - file path
   * @param {Object} data - data
   * @fulfil {Object} data - data
   * @returns {Promise}
   *
   * @example
   * writeConfigFile('config.json', { something: 'good' })
   *   .then(() => {
   *     console.log('data written')
   *   })
   */
  const writeConfigFile = (filename, data) => {
    return new Bluebird((resolve, reject) => {
      const contents = JSON.stringify(data, null, JSON_INDENT)
      fs.writeFile(filename, contents, (error) => {
        if (error) {
          reject(error)
        } else {
          resolve(data)
        }
      })
    })
  }
  
  /**
   * @summary Read all local settings
   * @function
   * @public
   *
   * @fulfil {Object} - local settings
   * @returns {Promise}
   *
   * @example
   * localSettings.readAll().then((settings) => {
   *   console.log(settings);
   * });
   */
  exports.readAll = () => {
    return readConfigFile(CONFIG_PATH)
  }
  
  /**
   * @summary Write local settings
   * @function
   * @public
   *
   * @param {Object} settings - settings
   * @fulfil {Object} settings - settings
   * @returns {Promise}
   *
   * @example
   * localSettings.writeAll({
   *   foo: 'bar'
   * }).then(() => {
   *   console.log('Done!');
   * });
   */
  exports.writeAll = (settings) => {
    return writeConfigFile(CONFIG_PATH, settings)
  }
  
  /**
   * @summary Clear the local settings
   * @function
   * @private
   *
   * @description
   * Exported for testing purposes
   *
   * @returns {Promise}
   *
   * @example
   * localSettings.clear().then(() => {
   *   console.log('Done!');
   * });
   */
  exports.clear = () => {
    return new Bluebird((resolve, reject) => {
      fs.unlink(CONFIG_PATH, (error) => {
        if (error) {
          reject(error)
        } else {
          resolve()
        }
      })
    })
  }
  