# frozen_string_literal: true

module ReleaseTools
  module Rollback
    # Presents a Validator instance in GitLab Markdown or Slack format
    class Presenter
      include ::SemanticLogger::Loggable

      LINK_FORMAT = 'https://gitlab.com/gitlab-org/security/gitlab/-/blob/%<commit>s/%<file>s'

      # comparison - Rollback::Comparison instance
      # deployment - Rollback::UpcomingDeployments instance
      # link_style - Either :markdown or :slack. Links will be presented in the requested style.
      def initialize(comparison, upcoming_deployment, link_style:)
        @comparison = comparison
        @upcoming_deployment = upcoming_deployment
        @link_style = link_style
      end

      def header
        if safe_to_rollback?
          ":large_green_circle: Rollback available"
        else
          ":red_circle: Rollback unavailable #{rollback_unavailable_header}"
        end
      end

      def present
        lines = [
          "*Current:* `#{@comparison.current_auto_deploy_package}`\n",
          "*Target:* `#{@comparison.target_auto_deploy_package}`\n"
        ]

        lines << "*Comparison:* #{@comparison.web_url}\n"

        lines << "*Comparison for each component:*\n"
        component_diffs.each do |diff|
          lines << "#{bullet} #{diff}\n"
        end

        lines
      end

      def unavailable_rollback_multireason?
        rollback_unavailable_reasons.size > 1
      end

      def rollback_unavailable_reasons_block
        rollback_unavailable_reasons.join("\n")
      end

      private

      def blob_url(file)
        format(LINK_FORMAT, commit: @comparison.current_rails_sha, file: file)
      end

      def safe_to_rollback?
        @comparison.safe? && !deployment_in_progress?
      end

      def deployment_in_progress?
        @upcoming_deployment.any?
      end

      def rollback_unavailable_header
        return unless rollback_unavailable_reasons.size == 1

        rollback_unavailable_reasons.first
      end

      def rollback_unavailable_reasons
        @rollback_unavailable_reasons ||= [].tap do |reasons|
          reasons << "- A deployment is in progress" if deployment_in_progress?
          reasons << "- Post-deployment migrations were executed after the target version on #{@comparison.minimum_version}" unless @comparison.safe?
        end
      end

      def bullet
        if @link_style == :markdown
          '-'
        else
          '•'
        end
      end

      def component_diffs
        Metadata::Presenter
          .new(@comparison.metadata_comparison, link_style: @link_style)
          .component_diffs
      end
    end
  end
end
