# Copyright:: Copyright (c) 2009-2026 Progress Software Corporation and/or its subsidiaries or affiliates. All Rights Reserved.
# Copyright:: Copyright (c) 2026 Cinc Project
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

require "rubygems"
require "bundler/gem_tasks"
Bundler::GemHelper.install_tasks

begin
  require "rspec/core/rake_task"

  desc "Run all knife specs"
  RSpec::Core::RakeTask.new(:spec) do |t|
    t.verbose = false
    t.rspec_opts = %w{--profile}
    t.pattern = FileList["spec/**/*_spec.rb"]

  end
rescue LoadError
  puts "rspec not available. bundle install first to make sure all dependencies are installed."
end

desc "Measure unit-test coverage accurately (per-file processes, merged with SimpleCov.collate)"
task :coverage do
  # A single whole-suite SimpleCov run under-reports knife's coverage: the
  # subcommand loader Kernel.loads command files, and Ruby's Coverage resets a
  # file's line counts every time it is re-loaded. Running each spec file in its
  # own process and merging the results with SimpleCov.collate avoids that.
  require "fileutils"

  parts_dir = "coverage_parts"
  FileUtils.rm_rf(parts_dir)
  FileUtils.rm_rf("coverage")

  specs = Dir["spec/unit/**/*_spec.rb"].sort
  abort "No unit specs found under spec/unit" if specs.empty?

  failed = []
  specs.each_with_index do |spec, i|
    printf("\r[%3d/%3d] %-72.72s", i + 1, specs.length, spec)
    env = {
      "COVERAGE" => "1",
      "SIMPLECOV_COMMAND_NAME" => spec,
      "SIMPLECOV_DIR" => File.join(parts_dir, i.to_s),
    }
    ok = system(env, "bundle", "exec", "rspec", "--no-color", spec, out: File::NULL, err: File::NULL)
    failed << spec unless ok
  end
  puts

  require "simplecov"
  result_files = Dir[File.join(parts_dir, "*", ".resultset.json")]
  SimpleCov.collate(result_files) do
    enable_coverage :branch
    add_filter "/spec/"
    add_filter "/vendor/"
  end
  FileUtils.rm_rf(parts_dir)

  unless failed.empty?
    warn "\n#{failed.length} spec file(s) had failures (coverage above still reflects what ran):"
    failed.each { |f| warn "  #{f}" }
    abort "rake coverage: some unit specs failed"
  end
end

begin
  require "cookstyle/chefstyle"
  require "rubocop/rake_task"

  namespace :style do
    desc "Run cookstyle style checks"
    RuboCop::RakeTask.new(:cookstyle) do |task|
      task.options += ["--display-cop-names", "--no-color"]
    end
  end

  # Alias for convenience
  desc "Run cookstyle style checks"
  task style: "style:cookstyle"
rescue LoadError
  puts "cookstyle/chefstyle is not available. (sudo) gem install cookstyle to do style checking."
end

desc "Run all quality tasks"
task quality: ["style:cookstyle"]

task default: [:spec]
