module PactBroker::Client::MergePacts

def almost_duplicate_message(original, new_interaction)

def almost_duplicate_message(original, new_interaction)
  "Two interactions have been found with same description (#{new_interaction[:description].inspect}) and provider state (#{(new_interaction[:providerState] || new_interaction[:providerStates]).inspect}) but a different request or response. " +
    "Please use a different description or provider state, or hard-code any random data.\n\n" +
    original.to_json + "\n\n" + new_interaction.to_json
end

def call pact_hashes

def call pact_hashes
  pact_hashes.reduce{|p1, p2| merge(p1, p2) }
end

def merge original, additional

Does not make any guarantees about order of interactions
Accepts two hashes representing pacts, outputs a merged hash
def merge original, additional
  new_pact = JSON.parse(original.to_json, symbolize_names: true)
  merge_interactions_or_messages(new_pact, original, additional, :interactions)
  merge_interactions_or_messages(new_pact, original, additional, :messages)
  new_pact
end

def merge_interactions_or_messages(new_pact, original, additional, key)

def merge_interactions_or_messages(new_pact, original, additional, key)
  return unless additional[key] || original[key]
  additional_messages_or_interactions = additional[key] || []
  original_messages_or_interactions = original[key] || []
  new_pact[key] ||= []
  additional_messages_or_interactions.each do |new_interaction|
    # check to see if this interaction matches an existing interaction
    overwrite_index = original_messages_or_interactions.find_index do |original_interaction|
      same_description_and_state?(original_interaction, new_interaction)
    end
    # overwrite existing interaction if a match is found, otherwise appends the new interaction
    if overwrite_index
      if new_interaction == original_messages_or_interactions[overwrite_index]
        new_pact[key][overwrite_index] = new_interaction
      else
        raise PactMergeError, almost_duplicate_message(original_messages_or_interactions[overwrite_index], new_interaction)
      end
    else
      new_pact[key] << new_interaction
    end
  end
end

def same_description_and_state? original, additional

def same_description_and_state? original, additional
  original[:description] == additional[:description] &&
    (
      (original[:providerState] && original[:providerState] == additional[:providerState]) ||
        (original[:providerStates] && original[:providerStates] == additional[:providerStates])
    )
end