# frozen_string_literal: true

module ReleaseTools
  module PublicRelease
    class GitlabPagesRelease
      include Release

      attr_reader :version, :client, :release_metadata

      def initialize(
        version,
        client: GitlabClient,
        release_metadata: ReleaseMetadata.new,
        commit: nil
      )
        @version = version.to_ce
        @client = client
        @release_metadata = release_metadata
        @commit = commit
      end

      def execute
        logger.info("Starting release of #{project.project_name}", version: version)

        create_target_branch

        return if SharedStatus.dry_run?

        compile_changelog
        update_versions

        tag = create_tag

        add_release_metadata(tag)
        notify_slack(project, version)
      end

      def compile_changelog
        return if version.rc?

        logger.info('Compiling changelog', project: project_path)

        ChangelogCompiler
          .new(project_path, client: client)
          .compile(version, branch: target_branch)
      end

      def update_versions
        logger.info(
          'Updating version files',
          project: project_path,
          version: version
        )

        commit_version_files(
          target_branch,
          { 'VERSION' => version.to_s }
        )
      end

      def create_tag
        logger.info('Creating tag', tag: tag_name, project: project_path)

        # Gitaly requires tags to be annotated tags, so we must specify a tag
        # message.
        client.find_or_create_tag(
          project_path,
          tag_name,
          target_branch,
          message: "Version #{tag_name}"
        )
      end

      def add_release_metadata(tag)
        meta_version = version.to_normalized_version

        logger.info(
          'Recording release data',
          project: project_path,
          version: meta_version,
          sha: tag.commit.id,
          tag: tag.name
        )

        release_metadata.add_release(
          name: project.project_name,
          version: meta_version,
          sha: tag.commit.id,
          ref: tag.name,
          tag: true
        )
      end

      def source_for_target_branch
        if @commit
          logger.info('Using specific commit', project: project_path, commit: @commit)
        end

        @commit || last_production_commit_metadata
      end

      private

      def project
        Project::GitlabPages
      end
    end
  end
end
