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

<%- if payload-%>
<%-
    	import "#{config.go_package}/converters"
			import :gen, "#{config.go_package}/gen/#{model.name.underscore}"
			import "#{config.go_package}/model"
-%>
func <%= model.name %>PayloadToModel(payload *gen.<%= payload.name %>) (*model.<%= model.name %>, error) {
	m := &model.<%= model.name %>{}
	if err := CopyFrom<%= model.name %>PayloadToModel(payload, m); err != nil {
		return nil, err
	}
	return m, nil
}

func CopyFrom<%= model.name %>PayloadToModel(payload *gen.<%= payload.name %>, m *model.<%= model.name %>) error {
  if payload == nil {
    return converters.NoPayloadGiven
  }
  if m == nil {
    return converters.NoModelGiven
  }

<%-
      assigned_field_names = []
      model.fields.each do |mf|
        pf_name = (mf.tags['payload'] || mf.name).downcase
        pf = payload.fields.detect{|pf| pf.name.downcase == pf_name }
        assigned_field_names.push(pf.name) if pf
        conv_pkg = mf.type.defined_in_model? ? 'model' : 'converters'
        if pf.nil?
-%>
  // <%= mf.name %> not found in <%= payload.name %> fields
<%-     elsif mf.type.assignable_with?(pf.type) -%>
  m.<%= mf.name %> = payload.<%= pf.name %>
<%-     elsif mf.type.pointee_of?(pf.type) -%>
  if payload.<%= pf.name %> != nil {
    m.<%= mf.name %> = *payload.<%= pf.name %>
  }
<%-     elsif !pf.type.needs_error_to_convert_to?(mf.type) -%>
  m.<%= mf.name %> = <%= conv_pkg %>.<%= pf.type.method_part_name %>To<%= mf.type.method_part_name %>(payload.<%= pf.name %>)
<%-     else -%>
<%-       meth = "#{pf.type.method_part_name}To#{mf.type.method_part_name}" -%>
<%-       if pf.type.pointer? -%>
  if payload.<%= pf.name %> != nil {
<%-       end -%>
  if v, err := <%= conv_pkg %>.<%= meth %>(<%= '*' if pf.type.pointer? %>payload.<%= pf.name %>); err != nil {
    return err
  } else {
    m.<%= mf.name %> = v
  }
<%-       if pf.type.pointer? -%>
  }
<%-       end -%>
<%-     end -%>
<%-   end -%>
<%-
      payload.fields.each do |pf|
        unless assigned_field_names.include?(pf.name)
-%>
  // No model field in <%= model.name %> for payload field "<%= pf.name %>"
<%-
        end
      end
-%>
  return nil
}
<%- end -%>

<%- if result -%>
<%-
    	import "#{config.go_package}/converters"
			import :gen, "#{config.go_package}/gen/#{model.name.underscore}"
			import "#{config.go_package}/model"
-%>
func <%= model.name %>ModelToResult(m *model.<%= model.name %>) (*gen.<%= result.name %>, error) {
  if m == nil {
    return nil, converters.NoModelGiven
  }
  r := &gen.<%= result.name %>{}

<%-
      assigned_field_names = []
      model.fields.each do |mf|
        rf_name = (mf.tags['result'] || mf.name).downcase
        rf = result.fields.detect{|rf| rf.name.downcase == rf_name }
        assigned_field_names.push(rf.name) if rf
        conv_pkg = mf.type.defined_in_model? ? 'model' : 'converters'
        if rf.nil?
-%>
  // <%= mf.name %> not found in <%= result.name %> fields
<%-     elsif rf.type.assignable_with?(mf.type) -%>
  r.<%= rf.name %> = m.<%= mf.name %>
<%-     elsif rf.type.pointer_of?(mf.type) -%>
  r.<%= rf.name %> = &m.<%= mf.name %>
<%-     elsif !mf.type.needs_error_to_convert_to?(rf.type) -%>
  r.<%= rf.name %> = <%= conv_pkg %>.<%= mf.type.method_part_name %>To<%= rf.type.method_part_name %>(m.<%= mf.name %>)
<%-     else -%>
<%-       meth = "#{mf.type.method_part_name}To#{rf.type.method_part_name}" -%>
  if v, err := <%= conv_pkg %>.<%= meth %>(m.<%= mf.name %>); err != nil {
    return err
  } else {
    r.<%= rf.name %> = v
  }
<%-     end -%>
<%-   end -%>
<%-
      result.fields.each do |rf|
        unless assigned_field_names.include?(rf.name)
-%>
    // No model field in <%= model.name %> for result field "<%= rf.name %>"
<%-
        end
      end
-%>
  return r, nil
}
<%- end -%>