# frozen_string_literal: true
# rubocop:todo all

# Copyright (C) 2009-2013 MongoDB Inc.
#
# 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 "bundler"
Bundler.setup

$LOAD_PATH.unshift(File.expand_path("../lib", __FILE__))

require "rake"
require "rake/extensiontask"
require "rspec/core/rake_task"
require 'fileutils'

load 'spec/shared/lib/tasks/candidate.rake'

def jruby?
  defined?(JRUBY_VERSION)
end

if jruby?
  require "rake/javaextensiontask"
  Rake::JavaExtensionTask.new do |ext|
    ext.name = "bson-ruby"
    ext.ext_dir = "src"
    ext.lib_dir = "lib"
    ext.target_version = ENV['TARGET_VERSION'] if ENV['TARGET_VERSION']
    ext.source_version = ENV['SOURCE_VERSION'] if ENV['SOURCE_VERSION']
  end
else
  require "rake/extensiontask"
  Rake::ExtensionTask.new do |ext|
    ext.name = "bson_native"
    ext.ext_dir = "ext/bson"
    ext.lib_dir = "lib"
  end
end

RSpec::Core::RakeTask.new(:rspec)

desc 'Build the bson gem'
task :build => [ :clean_all, *(jruby? ? :compile : nil) ] do
  command = [ 'gem', 'build' ]
  command << "--output=#{ENV['GEM_FILE_NAME']}" if ENV['GEM_FILE_NAME']
  command << ENV['GEMSPEC'] || 'bson.gemspec'
  system(*command)
end

# `rake version` is used by the deployment system so get the release version
# of the product beng deployed. It must do nothing more than just print the
# product version number.
desc 'Print the current version of the Ruby-BSON library'
task :version do
  require 'bson/version'
  puts BSON::VERSION
end

task :clean_all => :clean do
  %w[ bson-ruby.jar bson_native.bundle bson_native.so bson_native.o ].each do |file|
    FileUtils.rm_f(File.join(File.dirname(__FILE__), 'lib', file))
  end
end

task :spec => :compile do
  Rake::Task["rspec"].invoke
end

# overrides the default Bundler-provided `release` task, which also
# builds the gem. Our release process assumes the gem has already
# been built (and signed via GPG), so we just need `rake release` to
# push the gem to rubygems.
task :release do
  if ENV['GITHUB_ACTION'].nil?
    abort <<~WARNING
      `rake release` must be invoked from the `BSON Release` GitHub action,
      and must not be invoked locally. This ensures the gem is properly signed
      and distributed by the appropriate user.

      Note that it is the `rubygems/release-gem@v1` step in the `BSON Release`
      action that invokes this task. Do not rename or remove this task, or the
      release-gem step will fail. Reimplement this task with caution.

      NO GEMS were pushed to RubyGems.
    WARNING
  end

  # confirm: there ought to be two gems, one for MRI, and one for Java. These
  # will have been previously generated by the 'build' job.
  gems = Dir['*.gem']
  if gems.length != 2
    abort "Expected two gem files to be ready to release; got #{gems.inspect}"
  end

  gems.each do |gem|
    system 'gem', 'push', gem
  end
end

namespace :benchmark do

  task :prep do
    require_relative "perf/bench"
  end

  task ruby: [ :clean_all, 'benchmark:prep' ] do
    puts "Benchmarking pure Ruby..."
    benchmark!
  end

  task native: [ :compile, 'benchmark:prep' ] do
    puts "Benchmarking with native extensions..."
    benchmark!
  end

  namespace :decimal128 do
    task from_string: 'benchmark:prep' do
      puts "Benchmarking creating Decimal128 objects from a string"
      benchmark_decimal128_from_string!
    end

    task to_string: 'benchmark:prep' do
      puts "Benchmarking getting a string representation of a Decimal128"
      benchmark_decimal128_to_string!
    end
  end
end

task :default => [ :clean_all, :spec ]

desc "Generate all documentation"
task :docs => 'docs:yard'

namespace :docs do
  desc "Generate yard documention"
  task :yard do
    require 'bson/version'
    out = File.join('yard-docs', BSON::VERSION)
    FileUtils.rm_rf(out)
    system "yardoc -o #{out} --title bson-#{BSON::VERSION}"
  end
end
