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

export default DS.JSONSerializer.extend(DS.EmbeddedRecordsMixin, {

  serialize: function(snapshot, options){
    let hash = this._super(snapshot, options);
    for(var key in hash){
      hash[key.camelize()] = hash[key];
    delete hash[key];
    }
    hash.resourceType = snapshot.typeKey.capitalize();

    return hash;

  },

  hasEmbeddedOption: function(type, attr){
    var meta = type.metaForProperty(attr);
    return meta && meta.options.embedded;
  },

  hasSearchByOption: function(type, attr){
    var meta = type.metaForProperty(attr);
    return meta && meta.options.searchBy;
  },

  serializeIntoHash: function(hash, type, record, options){
    Ember.merge(hash, this.serialize(record, options));
  },

  keyForAttribute: function(key){
    return Ember.String.capitalize(key);
  },

  normalize: function(typeClass, hash){
    hash.id = hash.id || Ember.generateGuid({}, typeClass.typeKey);
    // var normalizedHash = this._super(typeClass, hash, prop);
    hash = buildLinksHash(this, this.store, typeClass, hash);
    return extractEmbeddedRecords(this, this.store, typeClass, hash);
  },

  extract: function(store, type, payload, id, requestType){
    if (payload == null) {
      return [];
    }

    if (payload.resourceType === "Bundle" && payload.total > 0) {
      // If this is DSTU1 you can use content in place of resource

      payload = payload.entry.mapBy("resource") || [];
    }

    payload.id = payload.id || id || Ember.generateGuid({}, type.typeKey);
    return this._super(store, type, payload, id, requestType);
  }
});

function buildLinksHash(serializer, store, typeClass, hash){
  var adapter = store.adapterFor(serializer);
  hash.links = hash.links || {};
  typeClass.eachRelationship(function(key){
    if(serializer.hasSearchByOption(typeClass, key)){
      var searchBy = typeClass.metaForProperty(key).options.searchBy;
      var query = {};
      query[searchBy] = hash.id;
      hash.links[key] = adapter.buildURL(key, null, null, 'fhirQuery', query);
    }
  });
  return hash;
}

// chooses a relationship kind to branch which function is used to update payload
// does not change payload if attr is not embedded
function extractEmbeddedRecords(serializer, store, typeClass, partial) {

  typeClass.eachRelationship(function(key, relationship) {
    if (serializer.hasDeserializeRecordsOption(key) || serializer.hasEmbeddedOption(typeClass, key)) {
      var embeddedTypeClass = store.modelFor(relationship.type);
      if (relationship.kind === "hasMany") {
        extractEmbeddedHasMany(store, key, embeddedTypeClass, partial);
      }
      if (relationship.kind === "belongsTo") {
        extractEmbeddedBelongsTo(store, key, embeddedTypeClass, partial);
      }
    }
  });

  return partial;
}

// handles embedding for `hasMany` relationship
function extractEmbeddedHasMany(store, key, embeddedTypeClass, hash) {
  if (!hash[key]) {
    return hash;
  }

  var ids = [];

  var embeddedSerializer = store.serializerFor(embeddedTypeClass.typeKey);
  hash[key].forEach(function(data) {
    var embeddedRecord = embeddedSerializer.normalize(embeddedTypeClass, data, null);
    store.push(embeddedTypeClass.typeKey, embeddedRecord);
    ids.push(embeddedRecord.id);
  });

  hash[key] = ids;
  return hash;
}


function extractEmbeddedBelongsTo(store, key, embeddedTypeClass, hash) {
  if (!hash[key]) {
    return hash;
  }

  var embeddedSerializer = store.serializerFor(embeddedTypeClass.typeKey);
  var embeddedRecord = embeddedSerializer.normalize(embeddedTypeClass, hash[key], null);
  store.push(embeddedTypeClass.typeKey, embeddedRecord);

  hash[key] = embeddedRecord.id;
  //TODO Need to add a reference to the parent later so relationship works between both `belongsTo` records
  return hash;
}

@@ -964,134 +964,8 @@
 y);%0A
-    // var normalizedHash = this._super(typeClass, hash, prop);%0A    hash = buildLinksHash(this, this.store, typeClass, hash);%0A
     
@@ -1494,479 +1494,8 @@
 );%0A%0A
-function buildLinksHash(serializer, store, typeClass, hash)%7B%0A  var adapter = store.adapterFor(serializer);%0A  hash.links = hash.links %7C%7C %7B%7D;%0A  typeClass.eachRelationship(function(key)%7B%0A    if(serializer.hasSearchByOption(typeClass, key))%7B%0A      var searchBy = typeClass.metaForProperty(key).options.searchBy;%0A      var query = %7B%7D;%0A      query%5BsearchBy%5D = hash.id;%0A      hash.links%5Bkey%5D = adapter.buildURL(key, null, null, 'fhirQuery', query);%0A    %7D%0A  %7D);%0A  return hash;%0A%7D%0A
 %0A// 

Remove build links hash code