# frozen_string_literal: true

module ReleaseTools
  module PatchRelease
    module BlogPost
      # This class implements the logic for the Merge Request that adds a
      # blog post to the gitlab.com (www-gitlab-com) repository.
      class MergeRequest < ReleaseTools::MergeRequest
        include ::SemanticLogger::Loggable
        include ReleaseTools::Security::IssueHelper
        include ReleaseTools::Security::MergeRequestHelper
        include Utils

        def project
          ReleaseTools::Project::WWWGitlabCom
        end

        def labels
          'patch release post'
        end

        def title
          "Draft: Adding #{versions_str} blog post"
        end

        def assignee_ids
          return appsec_release_managers&.collect(&:id) if security_fixes?

          release_managers&.collect(&:id)
        end

        def source_branch
          "create-#{hyphenated_version}-post"
        end

        def template_path
          File.expand_path('../../../../templates/patch_blog_post_merge_request_description.md.erb', __dir__)
        end

        def exists?
          (security_fixes? && security_blog_merge_request.present?) || super
        end

        def security_fixes?
          security_fixes.present?
        end

        def create
          blog_content = generate_blog_content
          file_commit.execute!(blog_content)

          return if SharedStatus.dry_run?

          # Create the MR on the remote repository.
          super
        end

        def patch_issue_url
          return "test.gitlab.com" if SharedStatus.dry_run?
          return unless patch_coordinator.single_version?

          Issue.new(version: versions.first).url
        end

        def generate_blog_content
          generator.execute
        end

        private

        def release_managers
          schedule.active_release_managers
        rescue ReleaseManagers::Schedule::VersionNotFoundError
          logger.fatal('Could not find active release managers')
          nil
        end

        def appsec_release_managers
          schedule.active_appsec_release_managers
        rescue ReleaseManagers::Schedule::VersionNotFoundError
          logger.fatal('Could not find active appsec release managers')
          nil
        end

        def schedule
          @schedule ||= ReleaseManagers::Schedule.new
        end

        def bug_fixes
          @bug_fixes ||= patch_coordinator.merge_requests(with_patch_version: true)
        end

        def versions
          return [bug_fixes.first[:version]] if patch_coordinator.single_version?

          if security_fixes?
            bug_fixes.map { |release| release[:version] }
          else
            bug_fixes.filter_map do |release|
              release[:version] if release[:pressure].positive?
            end
          end
        end

        def generator
          @generator ||= ReleaseTools::PatchRelease::BlogPost::MergeRequestContentGenerator.new(
            bug_fixes: bug_fixes,
            security_fixes: security_fixes,
            patch_coordinator: patch_coordinator,
            versions: versions
          )
        end

        def file_commit
          @file_commit ||= ReleaseTools::PatchRelease::BlogPost::FileCommit.new(
            versions: versions,
            project_path: project.path,
            source_branch: source_branch,
            target_branch: target_branch,
            security_fixes: security_fixes
          )
        end
      end
    end
  end
end
