#!/usr/bin/env lua-5.4

local posix = require"posix"
local isatty = posix.isatty

local os = require"bucket.os"
local fs = require"bucket.fs"
local term = require"bucket.ui.terminal"

local executable =
	fs.ExistsS"/bin/df"
	or fs.ExistsS"/usr/bin/df"
	-- if it doesn't exist search in $PATH/df
	if not executable then
		local string = require"bucket.string"
		executable = fs.SearchInPathT("df"
			,string.Gmatch1T(os.getenv"PATH","[^:]+")
			,function (file) return file~=arg[0] and fs.IsExecutable(file) end
		)[1]
		-- maybe its better to look for a binary executable instead of arg[0]
		-- which is possible via readS(file, 2)=="#!"
	end
	if not executable then
		os.exit(11, io.stderr:write("df not found?","\n"))
	end

-- if HOSTOS is freebsd and -l/--local is found, you must modify arg so it
-- filters out fuse.ssh and fuse.rclone
if os.getenv"HOSTOS"=="FreeBSD" or fs.Exists"/bin/freebsd-version" then
	-- -t is tricky, /^no/ -> everything after is excluded
	-- /no/ -> all exclusions are prefix based
	-- fuse.sshfs
	local a = {table.unpack(arg)}
	for k,v in pairs(a) do a[v] = k end
	-- -l doesn't care about inclusions, only cares about exclusions
	-- -t with -l
	-- -t could be run, but sanitizing this would be a nightmare
--	if a["-t"] and a["-l"] then
		-- io.stderr:write("mixing -l and -t is not supported for the moment")
		-- though it could be, but it would require parsing the option after -t
		-- then seeing if its set in a table
		-- and then...?
		-- os.exit(13)
--	elseif a["-l"] then
	if a["-l"] and a["-t"]==nil then
		-- local include = {
			-- "devfs","msdosfs","procfs","tmpfs","cd9660"
			-- ,"ufs","fdescfs","lindebugfs"
		-- }
		-- include = table.concat(include,",")

		local exclude = {"nfs", "fusefs.rclone", "fusefs.sshfs"}
		exclude = "no" .. table.concat(exclude, ",no")

		--[[
			lsvfs | awk '
				/network|fusefs/ {next}
				$2 ~ /^0x/ {printf("\"" $1 "\",")}
			'
		--]]

		table.insert(arg,1,"-t")
		table.insert(arg,2,
		-- table.concat({include, exclude}, ",")
			exclude
		)
	end
end

-- dont print color if piped
if isatty(0)==nil or isatty(1)==nil then
	-- os.exit() is redundant, posix.exec takes over
	os.exit(posix.exec(executable, arg))
end

-- in order of use%
-- ==0 white, divided by 20, >90 red
local colors = {"white","green","magenta","yellow"
	,"red" -- not divided by, special condition
}
colors[0] = "cyan" -- %0
local dividedby = 20 -- divided by 20, so it can only be 4 colors
-- the last one is over a percentage limit

local H = os.ExecuteH{executable,table.unpack(arg)}
print(H:read"l")
for line in H:lines() do
	local percentage = line:match"(%d+)%%"
	local n = math.tointeger( percentage )
	local c = colors[ n>90 and #colors or math.floor(n/dividedby) ]
	io.write( term.fgcolors[c] )
	print(line)
end

term.ChangeAttribute(term.sgrattr.reset)
os.exit(H:close())

--[==[ FREEBSD
-- freebsd's df -l does not care about local drives, so this fixes it, for now.
--[[
	local cachefile = string.format("%s/lsvfs_output",
			fs.ExistsS(os.getenv"XDG_CACHE_HOME")
			or fs.ExistsS(os.getenv"HOME" .. "/.cache")
			or fs.ExistsS(os.getenv"XDG_RUNTIME_DIR")
			or fs.ExistsS(os.getenv"TMPDIR")
			or "/tmp"
	)
	if fs.Exists(os.getenv"HOME"
	-- run mount, get the
	-- for _, col in ipairs(require"bucket.nix.mount"{}) do
	-- mtp, ext, zfs, ntfs, fat
	local include = {"fdescfs", "procfs", "ufs", "devfs"} do
		for _, val in ipairs(include) do
			include[val] = true
		end
	end

	local H
	for _, a in ipairs(arg) do
		if a=="-l" then H = io.popen"mount -p" break end
	end
	if H then
		local args_for_df = {}
		for device, mountpoint, fstype, options
			in H:read"a":gmatch(string.rep("(%g+)%s+",4) .. "[^\n]+")
			do
				if include[fstype] then
				end
		end
		executable = executable .. " " .. table.concat(args_for_df, " ")
	end
	--
	-- end
end
-- FREEBSD ]==]

--[[ REMINDER:
	df prints in batches, so you CANNOT speed it up
--]]
