Given /^(provider "[^"]*") has the following latest transactions:$/ do |provider, table|
  fake_transactions(provider, provider.default_service, table)
end

Given /^(provider "[^"]*") has the following latest transactions in (service "[^"]*"):$/ do |provider, service, table|
  fake_transactions(provider, service, table)
end

Given /^(provider "[^"]*") has no latest transactions$/ do |provider|
  FakeWeb.register_uri(
    :get, backend_url("/transactions/latest.xml?service_id=#{provider.services.first.id}&provider_key=#{provider.api_key}"),
    :status => fake_status(200), :body => '<transactions></transactions>')
end

Then /^I should see the following transactions:$/ do |table|
  data = process_transaction_table(table)

  table_node = find('#latest_transactions')

  data.each do |hash|
    assert table_node.has_css?('td', :text => hash[:buyer])
    assert table_node.has_css?('td', :text => hash[:timestamp])

    hash["Usage"].each do |name, value|
      assert(table_node.all('tr').any? do |tr|
        tr.has_css?('td', :text => name)
        tr.has_css?('td', :text => value)
      end)
    end
  end
end

def parse_hash(input)
  input.split(',').inject({}) do |memo, part|
    key, value = part.strip.split(':').map(&:strip)

    memo[key] = value
    memo
  end
end

def process_transaction_table(table)
  table.hashes.each do |row|
    row["Usage"] = parse_hash(row["Usage"])
  end
  table.hashes
end

def fake_transactions(provider, service, table)
  data = process_transaction_table(table)

  xml = Builder::XmlMarkup.new
  xml.transactions do
    transactions = data.each do |hash|
      application_id = if hash["Buyer"] == 'INVALID'
                         hash["Buyer"]
                       else
                         Account.find_by_org_name!(hash["Buyer"]).bought_cinstance.application_id
                       end

      xml.transaction :application_id => application_id, :timestamp => hash[:timestamp] do
        hash["Usage"].each do |name, value|
          metric_id = if name == 'INVALID'
                        name
                      else
                        service.metrics.find_by_system_name!(name).id
                      end

          xml.value value, :metric_id => metric_id
        end
      end
    end
  end

  FakeWeb.register_uri(
    :get, backend_url("/transactions/latest.xml?provider_key=#{provider.api_key}&service_id=#{service.id}"),
    :status => fake_status(200), :body => xml.target!)
end
