# -*- mode: ruby; coding: utf-8 -*-
# frozen_string_literal: true

load 'dataplx.gemspec' unless defined? DATAPLX_GEM

require 'bctgem/tasks'

BctGem.tasks(
  DATAPLX_GEM,
  syntax: { grep_v: /broken_sample/ },
  lint: {
    files: FileList[
      'lib/**/*.rb',
      'spec/**/*.rb',
      'dataplx.gemspec',
      'Rakefile',
      'Gemfile'
    ] - ['spec/dataplx/loaders/broken_sample.rb'],
  }
)

generated_docs = %i[
  docs-api/command-line.md
  docs-api/transform-index.md
  docs-api/transform-reference.md
  docs-api/topics/shortcuts.md
]

task doc: generated_docs

transform_sources = FileList['lib/dataplx/transforms/**/*.rb']

desc 'Generate dataplx command-line documentation'
file 'docs-api/command-line.md': %i[
  docs-api/command-line.erb.md
  lib/dataplx/version.rb
  lib/dataplx/cmd_line.rb
  lib/dataplx/doc.rb
] + transform_sources

desc 'Generate dataplx transform reference documentation'
file 'docs-api/transform-reference.md': %i[
  docs-api/transform-reference.erb.md
  lib/dataplx/version.rb
  lib/dataplx/doc.rb
] + transform_sources

desc 'Generate dataplx transform thematic index'
file 'docs-api/transform-index.md': %i[
  docs-api/transform-index.erb.md
  lib/dataplx/version.rb
  lib/dataplx/doc.rb
] + transform_sources

desc 'Generate dataplx pipeline shortcuts documentation'
file 'docs-api/topics/shortcuts.md': %i[
  docs-api/topics/shortcuts.erb.md
  lib/dataplx/version.rb
  lib/dataplx/transforms/mapping/pipeline.rb
] + transform_sources

rule(%r{^docs-api/[^.]*\.md$} => ->(f) { f.pathmap('%d/%n.erb.md') }) do |t|
  print "Generating #{t.name}.."
  require 'open3'
  out, err, status = Open3.capture3("erb -T - #{t.source}")
  if status.success?
    File.binwrite(t.name, out)
    puts '.'
  else
    puts "FAIL\n#{err}"
  end
end

nb_env = ENV.fetch('NOTEBOOK', '')
NOTEBOOKS = if nb_env.include?('/')
              FileList[nb_env.split(/\s+/)]
            else
              FileList["{spec,notebooks}/**/#{nb_env}*.ipynb"]
            end

namespace :notebooks do
  desc 'Execute notebooks in-place (carefully check the diffs!)'
  task exec: 'notebooks:clear' do
    system(*<<-EOS.split, *NOTEBOOKS)
      jupyter-nbconvert --inplace --to notebook --execute --allow-errors
    EOS
    sanitize_ipynb(NOTEBOOKS)
  end

  desc 'Clear output in notebooks'
  task 'clear' do
    # `jupyter-nbconvert --clear-output #{NOTEBOOKS.join(' ')}`
    # https://github.com/jupyter/nbconvert/issues/822
    system(*<<-EOS.split, *NOTEBOOKS)
      jupyter-nbconvert --inplace --to notebook
                        --ClearOutputPreprocessor.enabled=True
    EOS
  end

  desc 'Sanitize output in notebooks'
  task 'sanitize' do
    sanitize_ipynb(NOTEBOOKS)
  end

  def sanitize_ipynb(nbs)
    ruby(*%w[-Ilib bin/dataplx -v -c tools/sanitize_ipynb.dp --], *nbs)
  end

  desc 'Test notebooks'
  task 'test' do
    ruby(*%w[-Ilib spec/iruby_notebook_spec.rb])
  end
end

desc 'Run Transform examples from source'
task 'doctest' do
  ruby(*%w[-Ilib spec/doctest_spec.rb])
end

desc 'Run tests with summary-only output (for LLM workflows)'
task 'llmtest' do
  mkdir_p 'tmp'
  ENV['MINITEST_REPORTER'] = 'BenderReporter'
  ok = system('bundle exec rake test',
              out: 'tmp/test_out.txt', err: 'tmp/test_err.txt')
  lines = File.readlines('tmp/test_out.txt')
  start = lines.index { |l| l.include?('TIME RANKING') }
  puts start ? lines[start..].join : lines.last(20).join
  exit 1 unless ok
end

desc 'Bump VERSION/VERSION_DATE and re-run the rubygems notebook'
task :bump do
  new_version = ENV.fetch('VERSION') do
    abort 'Usage: rake bump VERSION=x.y.z'
  end
  today = Time.now.strftime('%Y-%m-%d')
  path = 'lib/dataplx/version.rb'
  src = File.binread(path)
  src.sub!(/^(\s*VERSION = )'[^']*'/, "\\1'#{new_version}'") ||
    abort("VERSION line not found in #{path}")
  src.sub!(/^(\s*VERSION_DATE = )'[^']*'/, "\\1'#{today}'") ||
    abort("VERSION_DATE line not found in #{path}")
  File.binwrite(path, src)
  puts "#{path}: VERSION=#{new_version}, VERSION_DATE=#{today}"
  notebooks = FileList['{spec,notebooks}/**/*rubygems*.ipynb']
  nbconvert = %w[uv run jupyter-nbconvert --inplace --to notebook]
  sh(*nbconvert, '--ClearOutputPreprocessor.enabled=True', *notebooks)
  sh(*nbconvert, '--execute', '--allow-errors', *notebooks)
  ruby(*%w[-Ilib bin/dataplx -v -c tools/sanitize_ipynb.dp --], *notebooks)
end


# MkDocs documentation generation

namespace :mkdocs do # rubocop:disable Metrics/BlockLength
  desc 'Generate MkDocs reference, index, command-line, shortcuts, changelog'
  task :generate do
    ruby(*%w[-Ilib tools/mkdocs_reference.rb])
    ruby(*%w[tools/mkdocs_cmdline.rb])
    ruby(*%w[tools/mkdocs_shortcuts.rb])
    ruby(*%w[tools/mkdocs_changelog.rb])
    ruby(*%w[-Ilib tools/mkdocs_examples.rb])
  end

  desc 'Build MkDocs site (host-agnostic html/ output)'
  task build: :generate do
    sh 'uv run --group doc mkdocs build'
    sh 'python3 tools/mkdocs_llms_postprocess.py'
  end

  desc 'Serve MkDocs locally'
  task serve: :generate do
    sh 'uv run --group doc mkdocs serve'
  end

  desc 'Build MkDocs PDF (pdf/DataPlx-Guide.pdf)'
  task pdf: :generate do
    # environment as a Hash: cmd.exe knows no `VAR=value command` prefix
    sh({ 'ENABLE_PDF_EXPORT' => '1' },
       'uv run --group doc mkdocs build -f mkdocs_pdf.yml')
    mkdir_p 'pdf'
    mv 'html/DataPlx-Guide.pdf', 'pdf/'
  end

  desc 'Build all: PDF first, then HTML+llms (post-processed)'
  task all: :generate do
    Rake::Task['mkdocs:pdf'].invoke
    Rake::Task['mkdocs:build'].invoke
  end
end

# StyleGuide/Ruby checks with Rubocop

#    task.options = %w[--debug --force-exclusion]


# This Gem was originally generated by 'mkstuff gem', here's how to re-run it:

desc 'Regenerate the Gem boiler-plate files'
task :mkstuff do
  system('mkstuff', 'gem', 'dataplx', '--cmdline', '-m', 'DataPlx',
         '--author', 'Christian Boos')
end
