local t = require('test.testutil')
local n = require('test.functional.testnvim')()

local clear = n.clear
local command = n.command
local eq = t.eq
local fn = n.fn

local pathsep = n.get_pathsep()
local testdir_left = 'Xtest-difftool-left'
local testdir_right = 'Xtest-difftool-right'

setup(function()
  n.mkdir_p(testdir_left)
  n.mkdir_p(testdir_right)
  t.write_file(testdir_left .. pathsep .. 'file1.txt', 'hello')
  t.write_file(testdir_left .. pathsep .. 'file2.txt', 'foo')
  t.write_file(testdir_left .. pathsep .. 'file4 with space.txt', 'hello')
  t.write_file(testdir_right .. pathsep .. 'file1.txt', 'hello world') -- modified
  t.write_file(testdir_right .. pathsep .. 'file3.txt', 'bar') -- added
  t.write_file(testdir_right .. pathsep .. 'file4 with space.txt', 'hello world') -- modified
end)

teardown(function()
  n.rmdir(testdir_left)
  n.rmdir(testdir_right)
end)

describe('nvim.difftool', function()
  before_each(function()
    clear()
    command('packadd nvim.difftool')
  end)

  it('shows added, modified, and deleted files in quickfix', function()
    command(('DiffTool %s %s'):format(testdir_left, testdir_right))
    local qflist = fn.getqflist()
    local entries = {}
    for _, item in ipairs(qflist) do
      table.insert(entries, { text = item.text, rel = item.user_data and item.user_data.rel })
    end

    -- Should show:
    -- file1.txt as modified (M)
    -- file2.txt as deleted (D)
    -- file3.txt as added (A)
    -- file4 with space.txt as modified (M)
    eq({
      { text = 'M', rel = 'file1.txt' },
      { text = 'D', rel = 'file2.txt' },
      { text = 'A', rel = 'file3.txt' },
      { text = 'M', rel = 'file4 with space.txt' },
    }, entries)
  end)

  it('has consistent split layout', function()
    command('set nosplitright')
    command(('DiffTool %s %s'):format(testdir_left, testdir_right))
    local wins = fn.getwininfo()
    local left_win_col = wins[1].wincol
    local right_win_col = wins[2].wincol
    assert(
      left_win_col < right_win_col,
      'Left window should be to the left of right window even with nosplitright set'
    )
  end)

  it('handles symlinks', function()
    -- Create a symlink in right dir pointing to file2.txt in left dir
    local symlink_path = vim.fs.joinpath(testdir_right, 'file2.txt')
    local target_path = vim.fs.joinpath('..', testdir_left, 'file2.txt')
    assert(vim.uv.fs_symlink(target_path, symlink_path) == true)
    finally(function()
      os.remove(symlink_path)
    end)
    assert(fn.getftype(symlink_path) == 'link')

    -- Run difftool
    command(('DiffTool %s %s'):format(testdir_left, testdir_right))
    local qflist = fn.getqflist()
    local entries = {}
    for _, item in ipairs(qflist) do
      table.insert(entries, { text = item.text, rel = item.user_data and item.user_data.rel })
    end

    -- file2.txt should not be reported as added or deleted anymore
    eq({
      { text = 'M', rel = 'file1.txt' },
      { text = 'A', rel = 'file3.txt' },
      { text = 'M', rel = 'file4 with space.txt' },
    }, entries)
  end)

  it('has autocmds when diff window is opened', function()
    command(('DiffTool %s %s'):format(testdir_left, testdir_right))
    local autocmds = fn.nvim_get_autocmds({ group = 'nvim.difftool.events' })
    assert(#autocmds > 0)
  end)

  it('cleans up autocmds when diff window is closed', function()
    command(('DiffTool %s %s'):format(testdir_left, testdir_right))
    command('q')
    local ok = pcall(fn.nvim_get_autocmds, { group = 'nvim.difftool.events' })
    eq(false, ok)
  end)

  it('does not reset quickfix list when closing quickfix window', function()
    command(('DiffTool %s %s'):format(testdir_left, testdir_right))
    local qflist_before = fn.getqflist()
    assert(#qflist_before > 0, 'quickfix list should not be empty')

    -- Close the quickfix window
    command('cclose')

    -- Quickfix list should still be intact
    local qflist_after = fn.getqflist()
    eq(#qflist_before, #qflist_after)

    -- Autocmds should still be active
    local autocmds = fn.nvim_get_autocmds({ group = 'nvim.difftool.events' })
    assert(#autocmds > 0, 'autocmds should still exist after closing quickfix window')
  end)

  it('opens difftool automatically when started with nvim -d', function()
    -- Start Neovim with -d flag for directory diff
    clear({
      args = {
        '--cmd',
        'packadd nvim.difftool',
        '-d',
        testdir_left,
        testdir_right,
      },
    })

    -- Wait for difftool to open
    n.poke_eventloop()

    -- Verify we have 3 windows (left, right, and quickfix)
    eq(3, #fn.getwininfo())

    -- Verify quickfix list has the expected entries
    local qflist = fn.getqflist()
    local entries = {}
    for _, item in ipairs(qflist) do
      table.insert(entries, { text = item.text, rel = item.user_data and item.user_data.rel })
    end
    eq({
      { text = 'M', rel = 'file1.txt' },
      { text = 'D', rel = 'file2.txt' },
      { text = 'A', rel = 'file3.txt' },
      { text = 'M', rel = 'file4 with space.txt' },
    }, entries)
  end)
end)
