#!/usr/bin/ruby
# frozen_string_literal: true

require 'test/unit'
require 'exif'
require 'fileutils'
require 'tmpdir'

class ExifNativeExtensionTest < Test::Unit::TestCase
  SAMPLE = '/usr/share/R/doc/html/logo.jpg'

  def setup
    skip("#{SAMPLE} not available (is r-base-core installed?)") unless File.file?(SAMPLE)
  end

  def test_require_loads_native_extension
    assert defined?(Exif), 'Exif constant should be defined'
    assert_equal 'Class', Exif.class.name
  end

  def test_new_without_arguments_creates_empty_object
    exif = Exif.new
    assert_kind_of Exif, exif
    entries = []
    exif.each_entry { |tag, value| entries << [tag, value] }
    assert_equal [], entries
  end

  def test_new_with_exif_jpeg_reads_metadata
    exif = Exif.new(SAMPLE)
    entries = []
    exif.each_entry { |tag, value| entries << [tag, value] }
    assert_operator entries.size, :>, 0

    keys = entries.map(&:first)
    assert keys.any? { |k| k.include?('Software') || k.include?('Orientation') || k.start_with?('0x') },
           "expected EXIF metadata tags, got: #{keys.inspect}"
  end

  def test_get_tag_by_name
    exif = Exif.new(SAMPLE)
    software = exif['Software']
    assert_kind_of String, software
    assert_operator software.length, :>, 0
  end

  def test_byte_order_constants
    assert_equal Exif::ByteOrder::MOTOROLA, Exif::ByteOrder::MOTOROLA
    assert_equal Exif::ByteOrder::INTEL, Exif::ByteOrder::INTEL
  end

  def test_ifd_constants
    assert_equal 0, Exif::IFD::Zero
    assert_equal(-1, Exif::IFD::Any)
  end

  def test_tag_description_lookup
    title, details = Exif['Make']
    assert_kind_of String, title
    assert_equal 'Manufacturer', title
    assert_kind_of Array, details
    assert_equal 'Make', details[0]
    assert_kind_of String, details[1]
    assert_match(/\A0x[0-9a-f]{4}\z/i, details[2])
  end

  def test_each_entry_with_tag_ids
    exif = Exif.new(SAMPLE)
    entries = []
    exif.each_entry(1) { |tag, value| entries << [tag, value] }
    assert_operator entries.size, :>, 0
    entries.each do |key, _value|
      assert_match(/\A0x[0-9a-f]{4}\z/i, key)
    end
  end

  def test_invalid_file_raises
    assert_raise(ArgumentError) { Exif.new('/nonexistent/path/to/image.jpg') }
  end

  def test_non_exif_file_raises
    path = File.join(Dir.tmpdir, 'ruby-exif-not-exif.txt')
    File.write(path, "not an image\n")
    begin
      assert_raise(Exif::NotExifFormat) { Exif.new(path) }
    ensure
      FileUtils.rm_f(path)
    end
  end

  def test_missing_tag_raises
    exif = Exif.new(SAMPLE)
    exif.ifd = Exif::IFD::GPS
    assert_raise(Exif::Error::TagNotFound) { exif['Make'] }
  end
end
