# frozen_string_literal: true

require_relative '../support/ubi_helper'
require_relative '../support/fips_helper'

module ReleaseTools
  module Services
    class SyncRemotesService
      include ::SemanticLogger::Loggable
      include ReleaseTools::Services::SyncRefsHelper
      include ReleaseTools::Support::UbiHelper
      include ReleaseTools::Support::FIPSHelper

      def initialize(version)
        @version = version.to_ce
        @omnibus = OmnibusGitlabVersion.new(@version.to_omnibus)
        @helm    = ReleaseTools::Helm::HelmVersionFinder.new.execute(version)
      end

      def execute
        logger.info('Syncing stable branches and tags', version: @version)

        return if SharedStatus.dry_run?

        # Sync component projects first, then the Rails project and last the packager projects.
        # This is done because the Rails monolith pipeline (that starts once the Rails branches are synced)
        #     looks for Gitaly tags.
        # Similarly, the packager project pipelines look for component project tags.
        sync_component_projects
        sync_gitlab_rails_project
        sync_packager_projects
      end

      # Syncs branches and tags for all component projects (Gitaly, Pages, KAS)
      # - Stable branches are of the form *-*-stable
      def sync_component_projects
        sync_branches(Project::Gitaly, @version.stable_branch(ee: false))
        sync_tags(Project::Gitaly, @version.tag(ee: false))

        sync_branches(Project::GitlabPages, @version.stable_branch)
        sync_tags(Project::GitlabPages, @version.tag)

        # rubocop:disable Style/GuardClause
        if Feature.enabled?(:release_the_kas)
          sync_branches(Project::Kas, @version.stable_branch(ee: false))
          sync_tags(Project::Kas, @version.tag(ee: false))
        end
        # rubocop:enable Style/GuardClause
      end

      # Syncs branches and tags of the Rails monolith projects (CE and EE)
      # - For GitLab ee stable branches are of the form *-*-stable-ee
      # - For GitLab FOSS stable branches are of the form *-*-stable
      def sync_gitlab_rails_project
        sync_branches(Project::GitlabCe, @version.stable_branch(ee: false))
        sync_tags(Project::GitlabCe, @version.tag(ee: false))

        sync_branches(Project::GitlabEe, @version.stable_branch(ee: true))
        sync_tags(Project::GitlabEe, @version.tag(ee: true))
      end

      # Syncs branches and tags of the Omnibus, CNG and Helm projects
      # - For Omnibus GitLab, stable branches are of the form *-*-stable.
      #   Omnibus uses a single branch post 12.2.
      # - For CNGImage, ee and regular stable branches are synced.
      def sync_packager_projects
        sync_branches(Project::OmnibusGitlab, @omnibus.to_ce.stable_branch)
        sync_tags(Project::OmnibusGitlab, @omnibus.to_ee.tag, @omnibus.to_ce.tag)

        sync_branches(Project::CNGImage, @version.to_ce.stable_branch)

        cng_tags = [@version.to_ce.tag, @version.to_ee.tag, ubi_tag(@version.to_ee)].tap do |versions|
          versions << fips_tag(@version.to_ee) if @version >= Version.new(GITLAB_FIPS_MINIMUM_VERSION)
        end
        sync_tags(Project::CNGImage, *cng_tags)

        sync_branches(Project::HelmGitlab, @helm.stable_branch)
        sync_tags(Project::HelmGitlab, @helm.tag)
      end
    end
  end
end
