namespace :katello do

namespace :upgrades do
  namespace '4.1' do
    desc "Removed orphaned pools and correct org+subscription mismatch"
    task :fix_invalid_pools => ["environment", "check_ping"] do
      logger = Logger.new(STDOUT)
      invalid_pools = Katello::Pool.all.select(&:invalid?)

      # Make sure Subscriptions are up to date for any org that has invalid pools
      org_ids = invalid_pools.map(&:organization_id).uniq.compact
      orgs = ::Organization.where(id: org_ids)
      orgs.each do |org|
        Katello::Subscription.import_all(org)
      end

      orphaned_pools = []

      invalid_pools.each do |pool|
        pool_json = Katello::Resources::Candlepin::Pool.find(pool.cp_id)

        correct_org = Organization.find_by(:label => pool_json['owner']['key'])
        unless correct_org
          orphaned_pools << pool
          logger.info("Pool id=#{pool.id} cp_id=#{pool.cp_id} will be removed because its organization does not exist")
          next
        end

        # authoritatively set the org id for this pool
        pool.organization = correct_org

        subscription = Katello::Pool.determine_subscription(
          product_id: pool_json['productId'],
          source_stack_id: pool_json['sourceStackId'],
          organization: correct_org
        )

        unless subscription
          orphaned_pools << pool
          logger.info("Pool id=#{pool.id} cp_id=#{pool.cp_id} will be removed because it has no matching subscription")
          next
        end

        pool.subscription = subscription

        # the matching subscription should have been imported above
        # with the right org assigned, import the pool and reindex associated hosts+activationkeys
        pool.import_data(true)
        logger.info("Pool id=#{pool.id} cp_id=#{pool.cp_id} has been reimported")
      rescue ::Katello::Errors::CandlepinPoolGone
        logger.info("Pool id=#{pool.id} cp_id=#{pool.cp_id} will be removed because it's not in Candlepin")
        orphaned_pools << pool
      end

      imported_count = invalid_pools.count - orphaned_pools.count
      logger.info("Corrected #{imported_count} invalid pools")

      orphaned_pools.each(&:destroy)
      logger.info("Removed #{orphaned_pools.count} orphaned pools")
    end
  end
end

end