# frozen_string_literal: true

OUTPUT_FILE = 'doc/update/breaking_windows.md'
DEPRECATIONS_PATH = 'data/deprecations'
TARGET_MILESTONE = '18.0'

WINDOWS = {
  1 => { date: 'April 21 - 23, 2025', time: '09:00 UTC to 22:00 UTC' },
  2 => { date: 'April 28 - 30, 2025', time: '09:00 UTC to 22:00 UTC' },
  3 => { date: 'May 5 - 7, 2025', time: '09:00 UTC to 22:00 UTC' }
}.transform_values { |v| v.merge(changes: []) }

def process_deprecations
  Dir.glob("#{DEPRECATIONS_PATH}/*.yml").each do |file|
    deprecations = YAML.safe_load(File.read(file), permitted_classes: [Date], symbolize_names: true)
    deprecations = [deprecations] unless deprecations.is_a?(Array)

    deprecations.each do |deprecation|
      next unless deprecation[:removal_milestone] == TARGET_MILESTONE && deprecation[:breaking_change] == true

      window = deprecation[:window].to_i
      WINDOWS[window][:changes] << deprecation if WINDOWS.key?(window)
    end
  end
end

def generate_markdown_file
  File.open(OUTPUT_FILE, 'w') do |file|
    write_metadata(file)
    # write_windows_content(file)
  end
end

def write_metadata(file)
  file.puts <<~METADATA
    ---
    stage: none
    group: none
    info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
    noindex: true
    title: Breaking change deployments on GitLab.com
    ---

    Changes are deployed continuously to GitLab.com. However, breaking changes
    can require more time to prepare for.

    In the month before the GitLab 19.0 release, breaking changes will be deployed
    during specific time windows. Closer to the 19.0 release, the dates for these windows
    will be announced and this page will list when each breaking change will be deployed.

    <!--
    Do not edit this page directly.
    This page is generated by lib/tasks/gitlab/docs/compile_windows.rake and
    from the yaml files in /data/deprecations.
    To update this file, run: bin/rake gitlab:docs:compile_windows
    -->
  METADATA
end

def write_windows_content(file)
  WINDOWS.each_with_index do |(window, data), index|
    file.puts <<~WINDOW
      ## Window #{window}

      This window takes place on #{data[:date]} from #{data[:time]}.

      | Deprecation | Impact | Stage | Scope | Check potential impact |
      |-------------|--------|-------|-------|------------------------|
    WINDOW

    data[:changes].each do |deprecation|
      deprecation_anchor = Gitlab::Help::HugoTransformer.new.hugo_anchor(deprecation[:title])
      file.puts "| [#{deprecation[:title]}](deprecations.md##{deprecation_anchor}) | " \
        "#{deprecation[:impact]&.capitalize} | #{deprecation[:stage]&.capitalize} | " \
        "#{deprecation[:scope]&.capitalize} | #{deprecation[:check_impact]} |"
    end

    file.puts unless index == WINDOWS.size - 1
  end
end

namespace :gitlab do
  namespace :docs do
    desc "Compile breaking changes windows into a single markdown file"
    task :compile_windows do
      require 'yaml'
      require 'date'
      require 'stringio'
      require_relative '../../../../lib/gitlab/help/hugo_transformer'

      process_deprecations
      generate_markdown_file

      puts "Breaking windows markdown file generated at #{OUTPUT_FILE}"
    end

    desc "Check that the breaking windows documentation is up to date"
    task :check_windows do
      require_relative '../../../../lib/gitlab/help/hugo_transformer'

      old_content = File.read(OUTPUT_FILE)
      process_deprecations
      new_content = StringIO.new
      write_metadata(new_content)
      write_windows_content(new_content)

      if old_content == new_content.string
        puts "#{COLOR_CODE_GREEN}INFO: Breaking windows documentation is up to date.#{COLOR_CODE_RESET}"

      else
        warn <<~WARNING
          #{COLOR_CODE_RED}ERROR: Breaking windows documentation is outdated!#{COLOR_CODE_RESET}
          To update the breaking windows documentation, either:

          - Run `bin/rake gitlab:docs:compile_windows` and commit the changes to this branch.
          - Have a technical writer resolve the issue.
        WARNING
        abort
      end
    end
  end
end
