Given(/^I have an Xbox XML$/) do
  @doc = Nokogiri::HTML(
    open("#{DOMAINS[:web_services]}/oa/metadata/wg_metadata.php/"\
          "dms_id/487/returnErr/1/XML_only/1/delivery_type/complete_album/"\
          "upc/888002951359")
  )

  puts @doc
end

Given(/^I have Itunes Tv XML$/) do
  @doc = Nokogiri::HTML(
    open("#{DOMAINS[:web_services]}/oa/metadata/"\
  "wg_itunes_XML.php/returnErr/1/XML_only/"\
  "1/delivery_type/complete_album/upc/885686530009"),
    nil,
    "UTF-8"
  )
  puts @doc
end

Given(/^I have Itunes Audio XML$/) do
  @doc = Nokogiri::HTML(
    open("#{DOMAINS[:web_services]}/oa/metadata/"\
  "wg_itunes_XML.php/returnErr/1/XML_only/"\
  "1/delivery_type/complete_album/upc/885686530009"),
    nil,
    "UTF-8"
  )
  puts @doc
end

Given(/^I have an Audio XML for dms (.*?) upc (.*?)$/) do |dms_id, upc|
  # returns "dms_master_master_id" based off input of
  # master id, profile type, product_type_id, "url" columns.  Url columns takes upc, dms_id
  @timeout = 100
  client = Support::DbClient.dd_client
  query = "SELECT dep.dms_master_master_id, ep.url
FROM encoding_profile ep
INNER JOIN dms_encoding_profile dep ON ep.encoding_profile_id = dep.encoding_profile_id
WHERE dep.dms_master_master_id = {dms_master_master_id}
AND ep.profile_type = 'metadata'
AND dep.product_type_id = 1
AND dep.order_type = 'release';"
  query = query.gsub("{dms_master_master_id}", dms_id)
  @url = client.query(query).first["url"]
  @url = (DOMAINS[:web_services]).to_s + @url
  @url = @url.gsub("{upc}", upc)
  @url = @url.gsub("{dms_master_master_id}", dms_id)
  @url = @url.gsub("{delivery_type}", "metadata_update")
  @url = @url.gsub("/mobile/{mobile}/clip_code/{clip_code}", "")
  @url += "/xml_only/1"
  puts @url
  @doc = Nokogiri::HTML(open(@url, read_timeout: @timeout))
end

Given(/^I have a film XML for dms (.*?) for upc (.*?)$/) do |dms_id, upc|
  @dms = dms_id
  # returns "dms_master_master_id" based off input of
  # master id, profile type, product_type_id, "url" columns.  Url columns takes upc, dms_id
  @url = Support::Helpers::XML.custom_film_dms_query(@dms)
  @url = (DOMAINS[:web_services]).to_s + @url
  @url = @url.gsub("{upc}", upc)
  @url = @url.gsub("{dms_master_master_id}", @dms)
  case @dms
  when "1", "392", "564", "487"
    @url = @url.gsub("{delivery_type}", "metadata_update")
  when "702", "731"
    @url = @url.gsub("{delivery_type}", "complete_album")
  end
  @url = @url.gsub("{product_type_id}", "3")
  @url = @url.gsub("/mobile/{mobile}/clip_code/{clip_code}", "")
  @url += "/xml_only/1"
  puts @url
  @doc = Nokogiri::HTML(open(@url, read_timeout: @timeout))
end

Given(/^I have an TV XML for dms (.*?) upc (.*?)$/) do |dms_id, upc|
  # returns "dms_master_master_id" based off input of
  # master id, profile type, product_type_id, "url" columns.  Url columns takes upc, dms_id
  client = Support::DbClient.dd_client
  query = "SELECT dep.dms_master_master_id, ep.url
FROM encoding_profile ep
INNER JOIN dms_encoding_profile dep ON ep.encoding_profile_id = dep.encoding_profile_id
WHERE dep.dms_master_master_id = {dms_master_master_id}
AND ep.profile_type = 'metadata'
AND dep.product_type_id = 2
AND dep.order_type = 'release';"
  query = query.gsub("{dms_master_master_id}", dms_id)
  @url = client.query(query).first["url"]
  @url = DOMAINS[:web_services] + @url
  @url = @url.gsub("{upc}", upc)
  @url = @url.gsub("{dms_master_master_id}", dms_id)
  @url = @url.gsub("{delivery_type}", "metadata_update")
  @url = @url.gsub("/mobile/{mobile}/clip_code/{clip_code}", "")
  @url += "/xml_only/1"
  puts @url
  @doc = Nokogiri::HTML(open(@url, read_timeout: @timeout))
end

Then(/^the XML should have an? (.*?) tag$/) do |node|
  expect(@doc.at_xpath("//#{node}")).to be_truthy
end

Then(/^the XML should have (.*) (.*?) tag\(s\)$/) do |count_of_subtitle_tags, node|
  expect(@doc.at_xpath("//#{node}")).to be_truthy
  subtitle_tags_in_doc = @doc.xpath("//#{node}").count
  expect(subtitle_tags_in_doc.to_s).to eq count_of_subtitle_tags
end

Then(/^the XML should have (.*) or more (.*?) tags$/) do |count_of_subtitle_tags, node|
  expect(@doc.at_xpath("//#{node}")).to be_truthy
  subtitle_tags_in_doc = @doc.xpath("//#{node}").count
  subtitle_tags_in_doc >= count_of_subtitle_tags.to_i
end

Then(/^There should be children nodes under (.*?) tag$/) do |node|
  expect(@doc.at_xpath("//#{node}/*")).to be_truthy
end

Then(/^The XML should have a node (.*?) with (.*?) tag/) do |node, text|
  expect(@doc.at_xpath("//#{node}[text()='#{text}']")).to be_truthy
end

Then(/^It should have valid music offer types$/) do
  intervals = @doc.at_xpath("//territory[text()='US']/..//intervals")
  expect(
    intervals.xpath("interval/end_date[text()='2017-03-01']/../wholesale_price_tier").inner_text
  ).to eq("3")
  expect(
    intervals.xpath("interval/end_date[text()='2017-03-07']/../wholesale_price_tier").inner_text
  ).to eq("34")
  expect(
    intervals.xpath("interval/end_date[text()='2017-03-18']/../wholesale_price_tier").inner_text
  ).to eq("40")
  expect(
    intervals.xpath("interval/end_date[text()='2017-03-25']/../wholesale_price_tier").inner_text
  ).to eq("33")
  expect(
    intervals.xpath("interval/start_date[text()='2017-03-25']/../wholesale_price_tier").inner_text
  ).to eq("3")
end

Then(/^It should have valid film offer types$/) do
  intervals = @doc.at_xpath("//territory[text()='US']/..//intervals")
  #  Mid Pricing Tier
  expect(
    intervals.xpath("interval/end_date[text()='2017-03-01']/../wholesale_price_tier").inner_text
  ).to eq("6")
  expect(
    intervals.xpath("interval/end_date[text()='2017-03-01']/../hd_wholesale_price_tier").inner_text
  ).to eq("108")
  #  Back Pricing Tier
  expect(
    intervals.xpath("interval/end_date[text()='2017-04-01']/../wholesale_price_tier").inner_text
  ).to eq("8")
  expect(
    intervals.xpath("interval/end_date[text()='2017-04-01']/../hd_wholesale_price_tier").inner_text
  ).to eq("111")
  # Front Pricing Tier
  expect(
    intervals.xpath("interval/end_date[text()='2017-05-01']/../wholesale_price_tier").inner_text
  ).to eq("1")
  expect(
    intervals.xpath("interval/end_date[text()='2017-05-01']/../hd_wholesale_price_tier").inner_text
  ).to eq("101")
end

# rubocop:disable Metrics/ParameterLists
Then(
  /^I get the xml for (.*?) with track (.*?) for (.*?) should be (.*?), (.*?), have (.*?) set/
) do |upc, tn, _ot, cfs, cfstream, _cfir|
  products = @doc.xpath("//track_number[text()='" + tn + "']/../products//territory[text()='US']/..")
  if upc == "191018253790" && (DOMAINS[:web_services].include? "theorchard")
    expect(products.xpath("cleared_for_stream").inner_text).to eq("false")
    expect(products.xpath("cleared_for_sale").inner_text).to eq("false")
  else
    expect(products.xpath("cleared_for_stream").inner_text).to eq(cfstream)
    expect(products.xpath("cleared_for_sale").inner_text).to eq(cfs)
    puts @url
  end
end
# rubocop:enable Metrics/ParameterLists

Then(/^I should see the store (.*?) is carvedout$/) do |dms|
  case dms
  when "1"
    expect(@doc.xpath("//cleared_for_sale[text()='true']").any?).to be_falsey
    expect(@doc.xpath("//cleared_for_sale[text()='false']").any?).to be_truthy
  when "286", "12", "187"
    expect(@doc.xpath("//takedown").any?).to be_truthy
  when "496"
    expect(@doc.xpath("//usetype [@userdefinedvalue='NoGoogleMusicBasic']").any?).to be_truthy
    expect(@doc.xpath("//usetype [@userdefinedvalue='NoGoogleMusicSubscription']").any?).to be_truthy
  end
end

Then(/^the Spotify xml for (.*?) for (.*?) with (.*?) upc/) do |tn, ot, upc|
  deallist = @doc.xpath("//dealreleasereference[text()='R" + tn + "']/..//dealterms//commercialmodeltype")
  puts "#{tn}, #{ot}, #{upc}"
  if upc == "191018253790" && (DOMAINS[:web_services].include? "theorchard")
    takedown = @doc.xpath("//takedown")
    expect(takedown.inner_text).to include("true")
  else
    case ot.downcase
    when "track download stream", "all"
      expect(deallist.inner_text).to include("SubscriptionModel")
      expect(deallist.xpath("/..//commercialmodeltype").any?).to be_falsey
    when "stream only", "album download stream"
      expect(deallist.inner_text).to include("SubscriptionModel")
      expect(deallist.xpath("/..//commercialmodeltype[text()='PayAsYouGoModel']").any?).to be_falsey
    when "track download only", "album track download"
      expect(deallist.xpath("/..//commercialmodeltype").any?).to be_falsey
      expect(@doc.xpath("//dealreleasereference[text"\
                      "()='R" + tn + "']/..//dealterms"\
                      "//commercialmodeltype[text()='SubscriptionModel']").any?).to be_falsey
    when "album download only", "none"
      #  Full Album Permanent Only and None goes by what the release has for commercial model type
      deallist = @doc.xpath("//dealreleasereference[text()='R0']/..")
      expect(deallist.xpath("/..//commercialmodeltype").any?).to be_falsey
    else
      fail "Can't find track \"#{tn}\" in the xml!"
    end
  end
end

# rubocop:disable Metrics/BlockLength
Then(/^the Amazon xml for (.*?) for (.*?) with (.*?) upc should be correct/) do |tn, ot, upc|
  deallist = @doc.xpath("//dealreleasereference[text()='R" + tn + "']/..//dealterms//commercialmodeltype")
  prime_on_demand = @doc.xpath("//usetype[@userdefinedvalue='PrimeOnDemandStream']")
  front_cover_image = @doc.xpath("//imagetype[contains(text(),'FrontCoverImage')]")

  if upc == "191018253790" && (DOMAINS[:web_services].include? "theorchard")
    takedown = @doc.xpath("//takedown")
    expect(takedown.inner_text).to include("true")
  else
    case ot.downcase
    when "track download stream", "all"
      expect(deallist.inner_text).to include("SubscriptionModel")
      expect(deallist.inner_text).to include("PayAsYouGoModel")
      expect(prime_on_demand.children.inner_text).to include("UserDefined")
      expect(front_cover_image.children.inner_text).to include("FrontCoverImage")
    when "stream only", "album download stream"
      expect(deallist.inner_text).to include("SubscriptionModel")
      expect(deallist.xpath("/..//commercialmodeltype[text()='PayAsYouGoModel']").any?).to be_falsey
    when "track download only", "album track download"
      expect(deallist.inner_text).to include("PayAsYouGoModel")
      expect(@doc.xpath("//dealreleasereference[text"\
                    "()='R" + tn + "']/..//dealterms"\
                    "//commercialmodeltype[text()='SubscriptionModel']"\
                    "/../takedown[text()='true']").any?).to be_truthy
    when "album download only", "none"
      #  Full Album Permanent Only and None goes by what the release has for commercial model type
      deallist = @doc.xpath("//dealreleasereference[text()='R0']/..")
      expect(deallist.inner_text).to include("PayAsYouGoModel")
    else
      fail "Can't find track \"#{tn}\" in the xml!"
    end
  end
end
# rubocop:enable Metrics/BlockLength

Then(/^the Google xml for (.*?) for (.*?) with (.*?) upc/) do |tn, ot, upc|
  puts "#{tn}, #{ot}, #{upc}"
  deallist = @doc.xpath("//dealreleasereference[text()='R" + tn + "']/..//usage//usetype")
  if upc == "191018253790" && (DOMAINS[:web_services].include? "theorchard")
    # upc is under 7123 and is carved out in production
    expect(deallist[0].values).to include("NoGoogleMusicBasic")
    expect(deallist[1].values).to include("NoGoogleMusicSubscription")
  else
    case ot.downcase
    when "album download only", "none"
      expect(deallist[0].values).to include("NoGoogleMusicBasic")
      expect(deallist[1].values).to include("NoGoogleMusicSubscription")
    when "track download stream", "all"
      expect(deallist[0].values).to include("GoogleMusicBasic")
      expect(deallist[1].values).to include("GoogleMusicSubscription")
    when "track download only", "album track download"
      expect(deallist[0].values).to include("GoogleMusicBasic")
      expect(deallist[1].values).to include("NoGoogleMusicSubscription")
    when "stream only", "album download stream"
      expect(deallist[0].values).to include("GoogleMusicSubscription")
      expect(deallist[1].values).to include("NoGoogleMusicBasic")
    else
      fail "Can't find track \"#{tn}\" in the xml!"
    end
  end
end

Then(/^there should be a (.*?) parent node with a (.*?) child node/) do |parent, child|
  expect(@doc.at_xpath("//#{parent}//#{child}")).to be_truthy
end

Then(/^I should see a (.*?) parent node with a (.*?) child node with (.*?) text/) do |parent, child, text|
  inner_text = @doc.at_xpath("//#{parent}//#{child}").text
  expect(inner_text).to eql(text)
end

And(/^I check that the XML has no territory nodes for other countries$/) do
  expect(@doc.at_xpath("//territory[text()='NZ']")).to be_falsey
  expect(@doc.at_xpath("//territory[text()='NO']")).to be_falsey
  expect(@doc.at_xpath("//territory[text()='MX']")).to be_falsey
  expect(@doc.at_xpath("//territory[text()='SE']")).to be_falsey
end

And(/^I am on the release metadata generator page$/) do
  visit(OA::ReleaseMetadataGeneratorPage) unless on(OA::ReleaseMetadataGeneratorPage).dms?
end

And(/^I generate tv XML for (.*?)$/) do |store|
  if on(OA::ReleaseMetadataGeneratorPage).dms.lstrip != store
    on(OA::ReleaseMetadataGeneratorPage) do |page|
      page.upc = "888831681496"
      page.dms = store
      page.submit
    end
  end
end

And(/^I generate film XML for (.*?)$/) do |store|
  if on(OA::ReleaseMetadataGeneratorPage).dms.lstrip != store
    on(OA::ReleaseMetadataGeneratorPage) do |page|
      page.upc = "888002415172"
      page.dms = store
      page.submit
    end
  end
end

Then(/^I get the XML from the page$/) do
  on(OA::ReleaseMetadataGeneratorPage) do |page|
    @doc = Nokogiri::HTML(page.xml_text)
    puts @doc
    message = @doc.at_xpath("//p/text()")
    # tag this with @wip if gating deployment
    fail "xml requirements changed!" if message && message.text.end_with?("Schema validation failure!")
  end
end

Then(/^I should see the localization data in the XML$/) do
  case @dms
  when "1"
    # maps locales from itunes XML
    locales = @doc.css("locales locale").map
    @film_localization_data.data.each do |localization|
      # find locale tag that matches language_code
      current_locale = locales.find { |x| x.attributes["name"].value == localization[:language_code] }
      # verify title matches
      title = current_locale.children.find { |y| y.name == "title" }.text
      expect(title).to eq localization[:name]
      # verify synopsis matches
      synopsis = current_locale.children.find { |y| y.name == "synopsis" }.text
      expect(synopsis).to eq localization[:long_synopsis]
    end
  when "487"
    # maps locales from movielabs XML
    locales = @doc.css("localizedinfo")
    @film_localization_data.data.each do |localization|
      xbox_language_code = localization[:language_code].split("-").first.upcase
      current_locale = locales.find { |x| x.attributes["language"].value == xbox_language_code }
      # verify title matches
      title = current_locale.children.find { |y| y.name == "titlesort" }.text
      expect(title).to eq localization[:name]
      # verify short synopsis matches
      synopsis = current_locale.children.find { |y| y.name == "summary190" }.text
      expect(synopsis).to eq localization[:short_synopsis]
      # verify long synopsis matches
      synopsis = current_locale.children.find { |y| y.name == "summary4000" }.text
      expect(synopsis).to eq localization[:long_synopsis]
    end
  end
end
