# frozen_string_literal: true

require 'kaitai/struct/visualizer/ksy_compiler'
require 'stringio'

module Kaitai::Struct::Visualizer
  describe KSYCompiler do
    before(:each) do
      @out = StringIO.new
      @c = KSYCompiler.new({}, 'ksv', @out)
    end

    context 'handling good formats' do
      before(:context) do
        @old_pwd = Dir.pwd
        Dir.chdir('spec/formats')
      end
      after(:context) { Dir.chdir(@old_pwd) }

      context '#compile_formats' do
        it 'compiles and loads "simple.ksy"' do
          pid = fork do
            main_class_name = @c.compile_formats(['simple.ksy'])

            expect(main_class_name).to eq 'Simple'
            expect(Kernel.const_defined?(main_class_name)).to be true
          end
          Process.wait(pid)
        end
      end
    end

    context 'handling erroneous formats' do
      before(:context) do
        @old_pwd = Dir.pwd
        Dir.chdir('spec/formats_err')
      end
      after(:context) { Dir.chdir(@old_pwd) }

      context '#resolve_yaml_path' do
        it 'resolves YAML paths generated by ksc in mappings' do
          node = @c.resolve_yaml_path('attr_bad_if2.ksy', %w[types foo_type instances foo if])
          expect(node.start_line).to eq 17
          expect(node.start_column).to eq 12
        end

        it 'resolves YAML paths generated by ksc in sequences' do
          node = @c.resolve_yaml_path('attr_bad_key.ksy', %w[seq 1 blah])
          expect(node.start_line).to eq 11
          expect(node.start_column).to eq 10
        end
      end

      context '#report_err' do
        it 'formats attr_bad_if2' do
          err_str = '[{"file": "attr_bad_if2.ksy",
            "message": "invalid type: expected boolean, got CalcIntType",
            "path": ["types", "foo_type", "instances", "foo", "if"]}]'
          err = JSON.parse(err_str)
          @c.report_err(err)
          expect(@out.string).to eq(
            "Error:\n\n" \
            "attr_bad_if2.ksy:18:13:/types/foo_type/instances/foo/if: invalid type: expected boolean, got CalcIntType\n"
          )
        end

        it 'formats yaml_dup_keys' do
          err_str = '[{"file": "yaml_dup_keys.ksy","line": 9,"col": 1,"message": "found duplicate key seq"}]'
          err = JSON.parse(err_str)
          @c.report_err(err)
          expect(@out.string).to eq(
            "Error:\n\n" \
            "yaml_dup_keys.ksy:9:1: found duplicate key seq\n"
          )
        end
      end
    end
  end
end
