# frozen_string_literal: true

require_relative 'test_helper'

class TestExpectations < Minitest::Test
  include TestHelpers

  def setup
    setup_temp_dirs
    @json_path = File.join(@tmpdir, 'test.json')
  end

  def teardown
    teardown_temp_dirs
  end

  def test_check_valid_file_with_all_expected_keys_returns_ok
    File.write(@json_path, JSON.pretty_generate('enabledPlugins' => {}))

    result = PluginConfig::Expectations.check(@json_path, %w[enabledPlugins])

    assert result[:ok]
  end

  def test_check_with_missing_keys_returns_schema_mismatch
    File.write(@json_path, JSON.pretty_generate('other' => {}))

    result = PluginConfig::Expectations.check(@json_path, %w[enabledPlugins])

    refute result[:ok]
    assert_includes result[:missing_keys], 'enabledPlugins'
    assert_match(/Missing required keys/, result[:error])
  end

  def test_check_missing_file_returns_file_missing
    result = PluginConfig::Expectations.check('/nonexistent/path.json', %w[enabledPlugins])

    refute result[:ok]
    assert_match(/File not found/, result[:error])
    assert_includes result[:missing_keys], 'enabledPlugins'
  end

  def test_check_invalid_json_returns_parse_error
    File.write(@json_path, '{{{not json')

    result = PluginConfig::Expectations.check(@json_path, %w[enabledPlugins])

    refute result[:ok]
    assert_match(/Invalid JSON/, result[:error])
  end

  def test_check_with_multiple_expected_keys
    File.write(@json_path, JSON.pretty_generate('name' => 'test', 'plugins' => []))

    result = PluginConfig::Expectations.check(@json_path, %w[name plugins])

    assert result[:ok]
  end

  # ─── SchemaError ─────────────────────────────────────────────────────

  def test_schema_error_to_diagnostic_json_returns_structured_output
    check_result = { ok: false, error: 'Missing required keys', missing_keys: %w[enabledPlugins] }
    error = PluginConfig::SchemaError.new(check_result)

    diag = error.to_diagnostic_json

    assert_equal 'schema_mismatch', diag[:error]
    assert_equal check_result, diag[:details]
  end

  def test_schema_error_message_matches_error_field
    check_result = { ok: false, error: 'test error message', missing_keys: [] }
    error = PluginConfig::SchemaError.new(check_result)

    assert_equal 'test error message', error.message
  end
end
