import Ember from 'ember';
import DS from 'ember-data';

export default Ember.Mixin.create({
  copyable: true,
  copy: function(options) {
    options = options || {};

    var _this = this;
    return new Ember.RSVP.Promise(function(resolve) {

      var model = _this.constructor;
      var copy = _this.get('store').createRecord(model.modelName || model.typeKey);
      var queue = [];

      model.eachAttribute(function(attr) {
        switch(Ember.typeOf(options[attr])) {
          case 'undefined':
            copy.set(attr, _this.get(attr));
            break;
          case 'null':
            copy.set(attr, null);
            break;
          default:
            copy.set(attr, options[attr]);
        }
      });

      model.eachRelationship(function(relName, meta) {
        var rel = _this.get(relName);
        if (!rel) { return; }

        var overwrite;
        var passedOptions = {};
        switch(Ember.typeOf(options[relName])) {
          case 'null':
          return;
          case 'instance':
            overwrite = options[relName];
            break;
          case 'object':
            passedOptions = options[relName];
            break;
          case 'array':
            overwrite = options[relName];
            break;
          default:
        }

        if (rel.constructor === DS.PromiseObject) {

          queue.push(rel.then(function(obj) {

            if (obj && obj.get('copyable')) {
              return obj.copy(passedOptions).then(function(objCopy) {
                copy.set(relName, overwrite || objCopy);
              });

            } else {
              copy.set(relName, overwrite || obj);
            }

          }));


        } else if (rel.constructor === DS.PromiseManyArray) {

          if (overwrite) {
            copy.get(relName).pushObjects(overwrite);
          } else {
            queue.push(rel.then(function(array) {
              var resolvedCopies =
                array.map(function(obj) {
                  if (obj.get('copyable')) {
                    return obj.copy(passedOptions);
                  } else {
                    return obj;
                  }
                });
              return Ember.RSVP.all(resolvedCopies).then(function(copies){
                copy.get(relName).pushObjects(copies);
              });
            }));
          }
        } else {
          if (meta.kind === 'belongsTo') {
            var obj = rel;

            if (obj && obj.get('copyable')) {
              queue.push( obj.copy(passedOptions).then(function(objCopy) {
                copy.set(relName, overwrite || objCopy);
              }));

            } else {
              copy.set(relName, overwrite || obj);
            }

          } else {
            var objs = rel;

            if (objs.get('content')) {
              objs = objs.get('content').compact();
            }

            if (objs.get('firstObject.copyable')) {

              var copies = objs.map(function(obj) {
                return obj.copy(passedOptions);
              });

              if (overwrite) {
                copy.get(relName).pushObjects(overwrite);
              } else {
                queue.push( Ember.RSVP.all(copies).then( function(resolvedCopies) {
                  copy.get(relName).pushObjects(resolvedCopies);
                }));
              }


            } else {
              copy.get(relName).pushObjects(overwrite || objs);
            }
          }

        }
      });


      Ember.RSVP.all(queue).then(function() {
        resolve(copy);
      });
    });
  }
});


@@ -1793,36 +1793,35 @@
 py.get(relName).
-push
+set
 Objects(overwrit
@@ -2267,36 +2267,35 @@
 py.get(relName).
-push
+set
 Objects(copies);
@@ -3098,36 +3098,35 @@
 py.get(relName).
-push
+set
 Objects(overwrit
@@ -3264,36 +3264,35 @@
 py.get(relName).
-push
+set
 Objects(resolved
@@ -3392,20 +3392,19 @@
 elName).
-push
+set
 Objects(

Set not push.