# frozen_string_literal: true

module ReleaseTools
  module Rollback
    # Given a changeset comparison, determines if a rollback is possible
    class Comparison
      include ::SemanticLogger::Loggable

      PROJECT = ReleaseTools::Project::GitlabEe.auto_deploy_path

      # The currently running (or upcoming) AutoDeploy::Version
      attr_reader :current

      # The AutoDeploy::Version to which we want to rollback
      attr_reader :target

      # Rollback cannot be performed to auto-deploy packages older than this version.
      attr_reader :minimum_version

      attr_reader :environment

      # current - ProductVersion which is currently running
      # target  - ProductVersion which we want to rollback to
      def initialize(current:, target:, environment:)
        @current = current
        @target = target
        @environment = environment
      end

      def execute
        @compare = Retriable.with_context(:api) do
          GitlabClient.compare(PROJECT, from: target_rails_sha, to: current_rails_sha)
        end

        @minimum_version = ReleaseTools::ProductVersion.from_metadata_sha(last_post_deploy_pipeline.sha)

        logger.info(
          'Rollback comparison',
          safe: safe?,
          web_url: web_url
        )

        self
      end

      def safe?
        target >= minimum_version
      end

      def web_url
        @compare.web_url
      end

      def current_package
        @current.to_s
      end

      def current_rails_sha
        @current[Project::GitlabEe.metadata_project_name].sha
      end

      def current_auto_deploy_package
        @current.auto_deploy_package
      end

      def target_package
        @target.to_s
      end

      def target_rails_sha
        @target[Project::GitlabEe.metadata_project_name].sha
      end

      def target_auto_deploy_package
        @target.auto_deploy_package
      end

      def metadata_comparison
        Metadata::Comparison.new(source: @current, target: @target)
      end

      private

      def last_post_deploy_pipeline
        env = environment.split('-').first

        Retriable.with_context(:api) do
          GitlabOpsClient.last_successful_deployment(ReleaseTools::Project::Release::Metadata, "db/#{env}")
        end
      end
    end
  end
end
