# frozen_string_literal: true

module Nokogiri
  module XML
    # Patch to add class?
    class Node
      def class?(*classes)
        present = false
        if attribute('class')
          present = true
          classes.each do |klass|
            present &&= self['class'].include? klass
          end
        end
        present
      end
    end
  end
end

# https://stackoverflow.com/a/42533209/368328
def command?(cmd)
  exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
  ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
    exts.each do |ext|
      exe = File.join(path, "#{cmd}#{ext}")
      return exe if File.executable?(exe) && !File.directory?(exe)
    end
  end
  nil
end

def commands?(commands)
  commands.map { |c| command? c }
end

def format_match(format, format_to_match)
  [:all, format_to_match].include? format
end

def gen_epub(name, format)
  return unless format_match(format, :epub)

  begin
    require 'paru/pandoc'
    Paru::Pandoc.new do
      from 'html'
      to 'epub'
      epub_metadata "metadata/#{name}.xml"
      epub_cover_image "covers/#{name}.jpg"
      metadata title: name
      data_dir Dir.pwd
      output "books/#{name}.epub"
    end.convert File.read("books/#{name}.html")
    puts '[epub] Generated EPUB file'
  rescue LoadError
    puts "[error] Can't generate EPUB without paru"
  end
end

def gen_mobi(name, format)
  if command?('ebook-convert') && format_match(format, :mobi)
    # Convert epub to a mobi
    `ebook-convert books/#{name}.epub books/#{name}.mobi`
    puts '[mobi] Generated MOBI file'
  else
    puts "[error] Can't generate MOBI without ebook-convert"
  end
end

def inside_docker?
  File.readlines('/proc/1/sched').each do |line|
    return line.strip != 'systemd (1, #threads: 1)'
  end
rescue Errno::ENOENT
  false
end

def gen_pdf(name, format)
  if commands?(%w[pandoc convert wkhtmltopdf pdftk]) && format_match(format, :pdf)
    # Generate PDF as well
    # First, lets make a better css version of the html
    `pandoc books/#{name}.html -s -c ../epub.css  -o books/#{name}_pdf.html`
    puts '[pdf] Generated html for pdf'

    # Print the pdf_html file to pdf
    if inside_docker?
      `xvfb-run wkhtmltopdf books/#{name}_pdf.html books/#{name}-nocover.pdf`
    else
      `wkhtmltopdf books/#{name}_pdf.html books/#{name}-nocover.pdf`
    end

    puts '[pdf] Generated PDF without cover'

    # Join the cover and pdf together
    `pdftk covers/#{name}.pdf books/#{name}-nocover.pdf cat output books/#{name}.pdf`
    puts '[pdf] Generated PDF file'
  else
    puts '[error] Please check README for PDF dependencies'
  end
end

def generate(name, format = :all)
  gen_epub(name, format)
  gen_mobi(name, format)
  gen_pdf(name, format)
end
