import arches from 'arches';
import AbstractModel from 'models/abstract';
import ko from 'knockout';
import koMapping from 'knockout-mapping';
import _ from 'underscore';

export default AbstractModel.extend({
    /**
    * A backbone model to manage function data
    * @augments AbstractModel
    * @constructor
    * @name FunctionModel
    */
    url: arches.urls.function,

    /**
    * Initializes the model with optional parameters
    * @memberof FunctionXGraphModel.prototype
    * @param {object} options
    * @param {object} options.functionid - the id of the function
    * @param {object} options.name - the name of the function
    * @param {object} options.description - the description of the function
    * @param {object} options.functiontype - the function type
    * @param {object} options.component - a reference to the knockout component
    * @param {object} options.defaultconfig - the default properties requiring user configuration
    */
    initialize: function (options) {
        var self = this;
        this._json = ko.observable('');
        this.functionid = options.functionid;
        this.defaultconfig = koMapping.fromJS({ 'triggering_nodegroups': [] });
        this.name = ko.observable();
        this.description = ko.observable();
        this.functiontype = ko.observable();
        this.component = ko.observable();

        this.parse(options);

        this.json = ko.computed(function () {
            return JSON.stringify(_.extend(JSON.parse(self._json()), {
                defaultconfig: koMapping.toJS(self.defaultconfig),
                name: self.name(),
                description: self.description(),
                functiontype: self.functiontype(),
                component: self.component(),
            }));
        });

        self.dirty = ko.computed(function () {
            return self.json() !== self._json();
        });
    },

    /**
    * parse - parses the passed in data into a {@link FunctionModel}
    * @memberof FunctionModel.prototype
    * @param  {object} data - the observable properties to seed a {@link FunctionModel} with
    * @param {object} data.functionid - the id of the function
    * @param {object} data.name - the name of the function
    * @param {object} data.description - the description of the function
    * @param {object} data.functiontype - the function type
    * @param {object} data.component - a reference to the knockout component
    * @param {object} data.defaultconfig - the default properties requiring user configuration
    */
    parse: function (data) {
        this._json(JSON.stringify(data));
        this.functionid = data.functionid;
        koMapping.fromJS(data.defaultconfig, this.defaultconfig);
        this.name(data.name);
        this.description(data.description);
        this.functiontype(data.functiontype);
        this.component(data.component);

        this.set('id', data.functionid);
    },

    /**
    * discard unsaved model changes and resets the model data
    * @memberof FunctionModel.prototype
    */
    reset: function () {
        this.parse(JSON.parse(this._json()));
    },

    /**
    * returns a JSON object containing model data
    * @memberof FunctionModel.prototype
    * @return {object} a JSON object containing model data
    */
    toJSON: function () {
        return JSON.parse(this.json());
    },
});
