-- Test that safe/normal Lua operations still work correctly

local function check(cond, msg)
    if not cond then
        error("FAIL: " .. msg)
    end
end

-- ============================================
-- MATH OPERATIONS
-- ============================================
local x = math.sin(1.5) + math.floor(3.7)
check(type(x) == "number", "Math operations failed")

check(math.abs(-5) == 5, "math.abs failed")
check(math.max(1, 2, 3) == 3, "math.max failed")
check(math.min(1, 2, 3) == 1, "math.min failed")
check(math.floor(3.9) == 3, "math.floor failed")
check(math.ceil(3.1) == 4, "math.ceil failed")

-- ============================================
-- STRING OPERATIONS
-- ============================================
local s = string.format("hello %d", 42)
check(s == "hello 42", "string.format failed")

local upper = string.upper("test")
check(upper == "TEST", "string.upper failed")

local lower = string.lower("TEST")
check(lower == "test", "string.lower failed")

local sub = string.sub("hello", 2, 4)
check(sub == "ell", "string.sub failed")

local len = string.len("hello")
check(len == 5, "string.len failed")

local rep = string.rep("ab", 3)
check(rep == "ababab", "string.rep failed")

local rev = string.reverse("hello")
check(rev == "olleh", "string.reverse failed")

-- ============================================
-- TABLE OPERATIONS
-- ============================================
local t = {1, 2, 3}
table.insert(t, 4)
check(#t == 4, "table.insert failed")
check(t[4] == 4, "table.insert value failed")

local removed = table.remove(t)
check(removed == 4, "table.remove failed")
check(#t == 3, "table.remove length failed")

local t2 = {3, 1, 2}
table.sort(t2)
check(t2[1] == 1 and t2[2] == 2 and t2[3] == 3, "table.sort failed")

local concat = table.concat({"a", "b", "c"}, ",")
check(concat == "a,b,c", "table.concat failed")

-- ============================================
-- ITERATION
-- ============================================
local count = 0
for i, v in ipairs({1, 2, 3, 4}) do
    count = count + 1
end
check(count == 4, "ipairs iteration failed")

count = 0
for k, v in pairs({a=1, b=2, c=3}) do
    count = count + 1
end
check(count == 3, "pairs iteration failed")

-- next function
local t3 = {a=1, b=2}
local k, v = next(t3)
check(k ~= nil and v ~= nil, "next function failed")

-- ============================================
-- ERROR HANDLING
-- ============================================
local ok, err = pcall(function()
    error("test error")
end)
check(not ok, "pcall should return false for error")
check(err:find("test error"), "Error message should contain 'test error'")

local ok2, result = pcall(function()
    return 42
end)
check(ok2 and result == 42, "pcall should return success value")

-- xpcall with traceback
local ok3, err3 = xpcall(function()
    error("xpcall test")
end, function(e)
    return "caught: " .. tostring(e)
end)
check(not ok3, "xpcall should return false for error")
check(err3:find("caught"), "xpcall error handler should run")

-- ============================================
-- TYPE CHECKS
-- ============================================
check(type({}) == "table", "type table failed")
check(type("") == "string", "type string failed")
check(type(123) == "number", "type number failed")
check(type(true) == "boolean", "type boolean failed")
check(type(nil) == "nil", "type nil failed")
check(type(function() end) == "function", "type function failed")

-- ============================================
-- CONVERSION
-- ============================================
check(tonumber("42") == 42, "tonumber string failed")
check(tonumber("3.14") == 3.14, "tonumber float failed")
check(tonumber("abc") == nil, "tonumber invalid failed")
check(tonumber(42) == 42, "tonumber number failed")

check(tostring(42) == "42", "tostring number failed")
check(tostring(true) == "true", "tostring boolean failed")
check(type(tostring({})) == "string", "tostring table failed")

-- ============================================
-- SELECT
-- ============================================
local a, b = select(2, 1, 2, 3)
check(a == 2 and b == 3, "select failed")
check(select("#", 1, 2, 3, 4) == 4, "select # failed")

-- ============================================
-- ASSERT
-- ============================================
local ok4, err4 = pcall(function()
    assert(true, "should not fail")
end)
check(ok4, "assert true failed")

local ok5, err5 = pcall(function()
    assert(false, "intentional fail")
end)
check(not ok5, "assert false should fail")
check(err5:find("intentional fail"), "assert message wrong")

-- ============================================
-- UTF8 (if available)
-- ============================================
if utf8 then
    local len = utf8.len("hello")
    check(len == 5, "utf8.len failed")
end

print("PASS: All safe operations work correctly")
