'use strict';

const Base = require('./base.js');
const joi = require('joi');

/**
 * @class DecentralizedComputation
 * @constructor
 * @extends Base
 * @description
 * Primarly serves as a schema for how DecentralizedComputations are published
 * and represented internally in datastores.
 * @param {object} opts
 * @param {string} opts.name what do we call this computation?
 * @param {string} opts.repository URL to repo where computation hosted
 * @param {string} opts.version e.g. x.x.x, 1.2.4. git version or semver tags preferred
 * @param {string} opts.local raw `Pipeline` definition
 * @param {string} opts.remote raw `Pipeline` definition
 * @param {(string|function)=} opts.setup command to run to prepare your computation in
 *                                 environments in which it will be run
 * @param {string=} opts.cwd will be squashed by system
 */
class DecentralizedComputation extends Base {
  /**
   * Get a serialized model suitable for saving in the 'computations' database.
   *
   * @returns {Object} Serialized model
   * @property {string} name
   * @property {string} url
   * @property {string} version
   */
  getComputationDocument() {
    const { name, repository: { url }, version } = this.serialize();

    return { name, url, version };
  }
}

DecentralizedComputation.schema = Object.assign({
  cwd: joi.string().min(2),
  name: joi.string().min(2).required(),
  plugins: joi.array().items(joi.string()),
  setup: joi.alternatives().try(
    joi.string(),
    joi.func()
  ),
  repository: joi.object().keys({
    url: joi.string().uri().min(9),
  }),
  version: joi.string().min(5).required(), // x.x.x
  local: joi.alternatives().try(
    joi.object().required(),
    joi.array().required()
  ).required(),
  remote: joi.alternatives().try(
    joi.object().required(),
    joi.array().required()
  ).required(),
}, Base.schema);

module.exports = DecentralizedComputation;

@@ -1041,16 +1041,51 @@
 d model%0A
+   * @property %7BObject%5B%5D%7D %5Binputs%5D%0A
    * @pr
@@ -1273,42 +1273,1239 @@
 ();%0A
-%0A    return %7B name, url, version %7D
+    const doc = %7B name, url, version %7D;%0A%0A    /**%0A     * Gather pipeline items' %60inputs%60 arrays and save them in the computation%0A     * document.%0A     *%0A     * @todo This is a temporary hack! It's to facilitate selectable ROIs for%0A     * Freesurfer analysis. See %7B@link https://github.com/MRN-Code/coinstac/issues/12%7D%0A     * for discussion on computation input/output.%0A     */%0A    const inputs = %5B%5D;%0A%0A    if (Array.isArray(this.local)) %7B%0A      this.local.forEach(localItem =%3E %7B%0A        if (DecentralizedComputation.hasInputs(localItem)) %7B%0A          inputs.push(localItem.inputs);%0A        %7D%0A      %7D);%0A    %7D else if (DecentralizedComputation.hasInputs(this.local)) %7B%0A      inputs.push(this.local.inputs);%0A    %7D%0A%0A    if (inputs.length) %7B%0A      doc.inputs = inputs;%0A    %7D%0A%0A    return doc;%0A  %7D%0A%0A  /**%0A   * Does an item have proper %60inputs%60?%0A   * @private%0A   * @static%0A   *%0A   * @todo This confirms the shape of an %60input%60. Change to a joi schema.%0A   * @throws %7BError%7D%0A   *%0A   * @param %7BObject%7D localItem%0A   * @returns %7Bboolean%7D%0A   */%0A  static hasInputs(localItem) %7B%0A    if (!(localItem instanceof Object)) %7B%0A      throw new Error('Expected arg to be an object');%0A    %7D%0A%0A    return 'inputs' in localItem && Array.isArray(localItem.inputs)
 ;%0A  

Add `inputs` to `DecentralizedComputation`'s doc save method.