local cwd = vim.fn.getcwd()

describe("lib.commands", function()
  local assert_eq = assert.is_equal
  local assert_true = assert.is_true
  local assert_false = assert.is_false

  before_each(function()
    vim.api.nvim_command("cd " .. cwd)
  end)

  local tbl = require("fzfx.commons.tbl")
  local CommandResult = require("fzfx.lib.commands").CommandResult
  local cmds = require("fzfx.lib.commands")
  local async = require("fzfx.commons.async")
  -- require("fzfx").setup()

  describe("[CommandResult]", function()
    it("new result is empty", function()
      local cr = CommandResult:new()
      assert_true(tbl.tbl_empty(cr.stdout))
      assert_true(tbl.tbl_empty(cr.stderr))
      assert_true(cr.code == nil)
    end)
    it("new result is not failed", function()
      local cr = CommandResult:new()
      assert_false(cr:failed())
    end)
  end)
  describe("[run_async]", function()
    it("run_async with stdout", function()
      async.void(function()
        local result = cmds.run_async({ "echo", "1" })
        print(string.format("run_async-stdout(echo 1):%s\n", vim.inspect(result)))
        assert_eq(type(result), "table")
        assert_eq(type(result.stdout), "table")
        if #result.stdout > 0 then
          assert_eq(result.stdout[1], "1")
        end
        assert_eq(type(result.stderr), "table")
        assert_eq(#result.stderr, 0)
        assert_eq(result.code, 0)
        assert_false(result:failed())
      end)()
    end)
    it("run_async with stderr", function()
      async.void(function()
        local result = cmds.run_async({ "cat", "non_exists.txt" })
        print(string.format("run_async-stderr(cat non_exists.txt):%s\n", vim.inspect(result)))
        assert_eq(type(result), "table")
        assert_eq(type(result.stdout), "table")
        assert_eq(#result.stdout, 0)
        assert_eq(type(result.stderr), "table")
        assert_true(#result.stderr >= 0)
        assert_eq(result.code, 1)
        assert_true(result:failed())
      end)()
    end)
    it("run_git_root_async", function()
      async.void(function()
        local result = cmds.run_git_root_async()
        print(string.format("run_git_root_async:%s\n", vim.inspect(result)))
        assert_eq(type(result), "table")
        assert_eq(type(result.stdout), "table")
        assert_true(#result.stdout > 0)
        print(string.format("git root:%s\n", vim.inspect(result.stdout)))
        assert_eq(type(result.stderr), "table")
        assert_eq(#result.stderr, 0)
        assert_eq(result.code, 0)
        assert_false(result:failed())
      end)()
    end)
    it("run_git_branches_async", function()
      async.void(function()
        local result1 = cmds.run_git_branches_async()
        print(string.format("run_git_branches_async-1:%s\n", vim.inspect(result1)))
        assert_eq(type(result1), "table")
        assert_eq(type(result1.stdout), "table")
        assert_true(#result1.stdout > 0)
        print(string.format("git branches-1(local):%s\n", vim.inspect(result1.stdout)))
        assert_eq(type(result1.stderr), "table")
        assert_eq(#result1.stderr, 0)
        assert_eq(result1.code, 0)
        assert_false(result1:failed())

        local result2 = cmds.run_git_branches_async(true)
        print(string.format("run_git_branches_async-2:%s\n", vim.inspect(result2)))
        assert_eq(type(result2), "table")
        assert_eq(type(result2.stdout), "table")
        assert_true(#result2.stdout > 0)
        print(string.format("git branches-2(remote):%s\n", vim.inspect(result2.stdout)))
        assert_eq(type(result2.stderr), "table")
        assert_eq(#result2.stderr, 0)
        assert_eq(result2.code, 0)
        assert_false(result2:failed())
      end)()
    end)
    it("run_git_current_branch_async", function()
      async.void(function()
        local result = cmds.run_git_current_branch_async()
        print(string.format("run_git_current_branch_async:%s\n", vim.inspect(result)))
        assert_eq(type(result), "table")
        assert_eq(type(result.stdout), "table")
        assert_true(#result.stdout > 0)
        print(string.format("git current branch(local):%s\n", vim.inspect(result.stdout)))
        assert_eq(type(result.stderr), "table")
        assert_eq(#result.stderr, 0)
        assert_eq(result.code, 0)
        assert_false(result:failed())
      end)()
    end)
    it("run_git_remotes_async", function()
      async.void(function()
        local result = cmds.run_git_remotes_async()
        print(string.format("run_git_remotes_async:%s\n", vim.inspect(result)))
        assert_eq(type(result), "table")
        assert_eq(type(result.stdout), "table")
        assert_true(#result.stdout > 0)
        print(string.format("git remotes:%s\n", vim.inspect(result.stdout)))
        assert_eq(type(result.stderr), "table")
        assert_eq(#result.stderr, 0)
        assert_eq(result.code, 0)
        assert_false(result:failed())
      end)()
    end)
  end)
  describe("[run_sync]", function()
    it("run_sync with stdout", function()
      local result = cmds.run_sync({ "echo", "1" })
      print(string.format("run_sync-stdout(echo 1):%s\n", vim.inspect(result)))
      assert_eq(type(result), "table")
      assert_eq(type(result.stdout), "table")
      if #result.stdout > 0 then
        assert_eq(result.stdout[1], "1")
      end
      assert_eq(type(result.stderr), "table")
      assert_eq(#result.stderr, 0)
      assert_eq(result.code, 0)
      assert_false(result:failed())
    end)
    it("run_sync with stderr", function()
      local result = cmds.run_sync({ "cat", "non_exists.txt" })
      print(string.format("run_sync-stderr(cat non_exists.txt):%s\n", vim.inspect(result)))
      assert_eq(type(result), "table")
      assert_eq(type(result.stdout), "table")
      assert_eq(#result.stdout, 0)
      assert_eq(type(result.stderr), "table")
      assert_true(#result.stderr >= 0)
      assert_eq(result.code, 1)
      -- assert_true(result:failed())
    end)
    it("run_git_root_sync", function()
      local result = cmds.run_git_root_sync()
      print(string.format("run_git_root_sync:%s\n", vim.inspect(result)))
      assert_eq(type(result), "table")
      assert_eq(type(result.stdout), "table")
      assert_true(#result.stdout > 0)
      print(string.format("git root:%s\n", vim.inspect(result.stdout)))
      assert_eq(type(result.stderr), "table")
      assert_eq(#result.stderr, 0)
      assert_eq(result.code, 0)
      assert_false(result:failed())
    end)
    it("run_git_branches_sync", function()
      local result1 = cmds.run_git_branches_sync()
      print(string.format("run_git_branches_sync-1:%s\n", vim.inspect(result1)))
      assert_eq(type(result1), "table")
      assert_eq(type(result1.stdout), "table")
      assert_true(#result1.stdout > 0)
      print(string.format("git branches-1(local):%s\n", vim.inspect(result1.stdout)))
      assert_eq(type(result1.stderr), "table")
      assert_eq(#result1.stderr, 0)
      assert_eq(result1.code, 0)
      assert_false(result1:failed())

      local result2 = cmds.run_git_branches_sync(true)
      print(string.format("run_git_branches_sync-2:%s\n", vim.inspect(result2)))
      assert_eq(type(result2), "table")
      assert_eq(type(result2.stdout), "table")
      assert_true(#result2.stdout > 0)
      print(string.format("git branches-2(remote):%s\n", vim.inspect(result2.stdout)))
      assert_eq(type(result2.stderr), "table")
      assert_eq(#result2.stderr, 0)
      assert_eq(result2.code, 0)
      assert_false(result2:failed())
    end)
    it("run_git_current_branch_sync", function()
      local result = cmds.run_git_current_branch_sync()
      print(string.format("run_git_current_branch_sync:%s\n", vim.inspect(result)))
      assert_eq(type(result), "table")
      assert_eq(type(result.stdout), "table")
      assert_true(#result.stdout > 0)
      print(string.format("git current branch(local):%s\n", vim.inspect(result.stdout)))
      assert_eq(type(result.stderr), "table")
      assert_eq(#result.stderr, 0)
      assert_eq(result.code, 0)
      assert_false(result:failed())
    end)
    it("run_git_remotes_sync", function()
      local result = cmds.run_git_remotes_sync()
      print(string.format("run_git_remotes_sync:%s\n", vim.inspect(result)))
      assert_eq(type(result), "table")
      assert_eq(type(result.stdout), "table")
      assert_true(#result.stdout > 0)
      print(string.format("git remotes:%s\n", vim.inspect(result.stdout)))
      assert_eq(type(result.stderr), "table")
      assert_eq(#result.stderr, 0)
      assert_eq(result.code, 0)
      assert_false(result:failed())
    end)
  end)
end)
