<%-
def method_calling_exp(m, argument)
  if m.is_a?(Array)
    m.reverse.join('(') + argument + (')' * m.length)
  else
    "#{m}(#{argument})"
  end
end
-%>
package controller

import (
	"<%= config.go_package %>/app"
	"<%= config.go_package %>/model"
)

<%- types.select(&:gen_converter?).each do |type| -%>
<%-   if type.payload -%>
func <%= type.name %>PayloadToModel(payload *app.<%= type.payload_name %>) (*model.<%= type.name %>, error) {
	model := &model.<%= type.name %>{}
	if err := CopyFrom<%= type.name %>PayloadToModel(payload, model); err != nil {
		return nil, err
	}
	return model, nil
}

func CopyFrom<%= type.name %>PayloadToModel(payload *app.<%= type.payload_name %>, model *model.<%= type.name %>) error {
  if payload == nil {
    return NoPayloadGiven
  }
  if model == nil {
    return NoModelGiven
  }

<%-
      type.fields_including_id.each do |f|
      pf = type.payload.fields.detect{|pf| f.name.underscore == pf.name }
      if pf.nil?
-%>
  // <%= f.name %> not found in payload fields
<%-
      else
        simple, with_error, method_name = f.payload_assignment_options(pf)
-%>
<%-     if simple -%>
  model.<%= f.name %> = payload.<%= f.name %>
<%-     elsif !with_error -%>
  model.<%= f.name %> = <%= method_calling_exp(method_name, "payload.#{f.name}") %>
<%-     else -%>
  if v, err := <%= method_calling_exp(method_name, "payload.#{f.name}") %>; err != nil {
    return err
  } else {
    model.<%= f.name %> = v
  }
<%-     end -%>
<%-   end -%>
<%- end -%>
<%- type.payload.field_diffs(type.fields_including_id.map{|f| f.name.underscore}).each do |pf| -%>
  // No model field for payload field "<%= pf.name %>"
<%- end -%>
  return nil
}

<%-   end -%>
<%-   if type.media_type -%>
func <%= type.name %>ModelToMediaType(model *model.<%= type.name %>) (*app.<%= type.media_type_name_for_go %>, error) {
  if model == nil {
    return nil, NoModelGiven
  }
  r := &app.<%= type.media_type_name_for_go %>{}

<%-
      type.fields_including_id.each do |f|
        mf = type.media_type.fields.detect{|mf| f.name.underscore == mf.name }
        if mf.nil?
-%>
  // <%= f.name %> not found for media type field
<%-
        else
          simple, with_error, method_name = f.media_type_assignment_options(mf)
-%>
<%-       if simple -%>
  r.<%= mf.goa_name %> = model.<%= f.name %>
<%-       elsif !with_error -%>
  r.<%= mf.goa_name %> = <%= method_calling_exp(method_name, "model.#{f.name}") %>
<%-       else -%>
  if val, err := <%= method_calling_exp(method_name, "model.#{f.name}") %>; err != nil {
     return nil, err
  } else {
    r.<%= mf.goa_name %> = val
  }
<%-       end
        end -%>
<%-   end -%>
<%-   type.media_type.field_diffs(type.fields_including_id.map{|f| f.name.underscore}).each do |mf| -%>
    // No model field for media type field "<%= mf.name %>"
<%-   end -%>
  return r, nil
}

<%-   end -%>
<%- end -%>