# typed: strict
# frozen_string_literal: true

require "formula_versions"

#
# {CaskDescriptionCacheStore} provides methods to fetch and mutate cask descriptions used
# by the `brew desc` and `brew search` commands.
#
class CaskDescriptionCacheStore < DescriptionCacheStore
  Key = type_member { { fixed: String } }
  Value = type_member { { fixed: T.anything } }

  # If the database is empty `update!` it with all known casks.
  #
  # @return [nil]
  sig { override.params(eval_all: T::Boolean).void }
  def populate_if_empty!(eval_all: Homebrew::EnvConfig.tap_trust_configured?)
    return unless eval_all
    return unless database.empty?

    Cask::Cask.all(eval_all:)
              .each { |c| update!(c.full_name, [c.name.join(", "), c.desc.presence]) }
  end

  # Use an update report to update the {CaskDescriptionCacheStore}.
  #
  # @param report [Report] an update report generated by cmd/update.rb
  # @return [nil]
  sig { override.params(report: ReporterHub).void }
  def update_from_report!(report)
    unless Homebrew::EnvConfig.tap_trust_configured?
      database.clear!
      return
    end
    return populate_if_empty! if database.empty?
    return if report.empty?

    alterations = T.cast(
      report.select_formula_or_cask(:AC) +
      report.select_formula_or_cask(:MC),
      T::Array[String],
    )
    deletions = T.cast(report.select_formula_or_cask(:DC), T::Array[String])

    update_from_cask_tokens!(alterations)
    delete_from_cask_tokens!(deletions)
  end

  # Use an array of cask tokens to update the {CaskDescriptionCacheStore}.
  #
  # @param cask_tokens [Array] the casks to update
  # @return [nil]
  sig { params(cask_tokens: T::Array[String]).void }
  def update_from_cask_tokens!(cask_tokens)
    unless Homebrew::EnvConfig.tap_trust_configured?
      database.clear!
      return
    end
    return populate_if_empty! if database.empty?

    cask_tokens.each do |token|
      c = Cask::CaskLoader.load(token)
      update!(c.full_name, [c.name.join(", "), c.desc.presence])
    rescue Cask::CaskUnavailableError, Homebrew::UntrustedTapError, *FormulaVersions::IGNORED_EXCEPTIONS
      delete!(token)
    end
  end
end
