# frozen_string_literal: true

require 'version_sorter'

module ReleaseTools
  # Utility methods for dealing with version numbers and version.gitlab.com
  class Versions
    def self.current
      ReleaseTools::VersionClient
        .versions
        .collect(&:version)
    end

    # Returns the last version for the given major version, or `nil` if none
    # could be found.
    def self.last_version_for_major(major)
      # Filter versions that start with the major version
      filtered_versions = current.select { |v| v.start_with?("#{major}.") }
      # Sort them by semantic version and get the latest version (last in the sorted array)
      sort(filtered_versions).last
    end

    # Given an Array of version numbers, return the next patch versions
    #
    # Example:
    #
    #   next(['1.0.0', '1.1.0', '1.1.1', '1.2.3'])
    #   => ['1.0.1', '1.1.1', '1.1.2', '1.2.4']
    def self.next(versions)
      versions.map do |version|
        ReleaseTools::Version.new(version).next_patch
      end
    end

    # Given an Array of version strings, find the `count` latest by minor number
    #
    # versions - Array of version strings
    # count    - Number of versions to return (default: 3)
    #
    # Example:
    #
    #   latest(['1.0.0', '1.1.0', '1.1.1', '1.2.3'], 3)
    #   => ['1.2.3', '1.1.1', '1.0.0']
    def self.latest(versions, count = 3)
      ::VersionSorter.rsort(versions).uniq do |version|
        version.split('.').take(2)
      end.take(count)
    end

    # Get the next three patch versions
    def self.next_versions
      self.next(latest(current, 3))
    end

    def self.sort(versions)
      ::VersionSorter.sort(versions).uniq
    end

    def self.current_stable_branch
      next_versions.first.stable_branch(ee: true)
    end

    def self.current_version
      ReleaseTools::Version.new(next_versions.first.to_minor)
    end
  end
end
