# frozen_string_literal: true

# Human Readable Jupyter Diffs
module IpynbDiff
  require 'transformer'
  require 'diffy'

  @default_transform_options = {
    include_metadata: false,
    cell_decorator: :html
  }

  @default_diff_options = {
    preprocess_input: true,
    write_output_to: nil,
    format: :text,
    sources_are_files: false,
    raise_if_invalid_notebook: false,
    transform_options: @default_transform_options,
    diff_opts: {
      include_diff_info: false
    }
  }.freeze

  def self.prepare_input(to_prepare, options)
    return '' unless to_prepare

    prep = to_prepare
    prep = File.read(prep) if options[:sources_are_files]
    prep = transform(prep, raise_errors: true, options: options[:transform_options]) if options[:preprocess_input]
    prep
  end

  def self.diff(
    from_notebook,
    to_notebook,
    options = @default_diff_options
  )
    options = @default_diff_options.merge(options)

    from = prepare_input(from_notebook, options)
    to = prepare_input(to_notebook, options)

    d = Diffy::Diff.new(from, to, **options[:diff_opts]).to_s(options[:format])
    File.write(options[:write_output_to], d) if options[:write_output_to]
    d
  rescue InvalidNotebookError
    raise if options[:raise_if_invalid_notebook]
  end

  def self.transform(notebook, raise_errors: false, options: @default_transform_options)
    options = @default_transform_options.merge(options)

    Transformer.new(**options).transform(notebook)
  rescue InvalidNotebookError
    raise if raise_errors
  end
end
