local FORMNAME = "fediauth-onboard"
local FORMNAMEFEDI = "fediauth-onboard-fedi"

local feditempstore = {}

function string.starts(String,Start)
   return string.sub(String,1,string.len(Start))==Start
end

minetest.register_chatcommand("fediauth_off", {
    description = "Disable the fediauth verification",
    privs = { fediauth_enabled = true, interact = true },
    func = function(name)
        -- clear priv
        local privs = minetest.get_player_privs(name)
        privs.fediauth_enabled = nil
        minetest.set_player_privs(name, privs)
        return true, "fediauth login disabled"
    end
})

minetest.register_chatcommand("fediauth_on", {
    description = "Enable the fediauth verification",
    privs = { interact = true },
    func = function(name)
        local secret_b32 = fediauth.get_player_secret_b32(name)

		local formspec_account = "size[9,10]" ..
            "label[1,7;Input your fediverse account handle]" ..
			"image[1.5,0.6;7,7;fediverse.png]" ..
            "field[1,9;4,1;fediverse_account_url;@nick@example.com;]" .. 
	    "field_close_on_enter[fediverse_account_url;false]" ..
            "button[5,8.7;3,1;submit;Send code]"

        minetest.show_formspec(name, FORMNAMEFEDI, formspec_account)
        end
})

minetest.register_on_player_receive_fields(function(player, formname, fields)
    if formname ~= FORMNAME and formname ~= FORMNAMEFEDI then
        return
    end

    if fields.fediverse_account_url then
        local playername = player:get_player_name()
	-- basic prevent mention spam and limit length
	if not string.starts(fields.fediverse_account_url, "@") or string.len(fields.fediverse_account_url) < 3 or string.len(fields.fediverse_account_url) > 100 then
		minetest.chat_send_player(playername, minetest.colorize("#ff0000", "Try again, your input is incorrect"))
		return
	end
	local fedihandle = fields.fediverse_account_url:split("@")
	if #fedihandle ~= 2 then
		minetest.chat_send_player(playername, minetest.colorize("#ff0000", "Incorrect format"))
		return
	end
	if fediauth.check_for_restricted_instance(fedihandle[2]) then
		minetest.chat_send_player(playername, minetest.colorize("#ff0000", fedihandle[2] .. " has restricted, try another..."))
		return
	end
        local secret_b32 = fediauth.get_player_secret_b32(playername)
        local codeseq = fediauth.give_code(secret_b32)
	if fediauth.is_home_instance(fedihandle[2]) then
		fediauth.send_code(codeseq[1], "@" .. fedihandle[1], playername)
	else
		fediauth.send_code(codeseq[1], "@" .. fedihandle[1] .. "@" .. fedihandle[2], playername)
	end
	feditempstore[playername] = fields.fediverse_account_url
	local formspec = "size[9,10]" ..
            "label[1,7;Check code on " .. minetest.formspec_escape(fields.fediverse_account_url) .. "]" ..
            "field[1,9;4,1;code;Code;]" ..
            "button_exit[5,8.7;3,1;submit;Verify]"

        minetest.show_formspec(playername, FORMNAME, formspec)

    end

    if fields.code then
        local playername = player:get_player_name()
        local secret_b32 = fediauth.get_player_secret_b32(playername)
        if fediauth.check_code(secret_b32, fields.code) then
            -- set priv
            local privs = minetest.get_player_privs(playername)
            privs.fediauth_enabled = true
            minetest.set_player_privs(playername, privs)
	    fediauth.verified_checkmark(player, true)
	    if feditempstore[playername] then
	    	fediauth.storage:set_string(playername .. "_fedi", feditempstore[playername])
		feditempstore[playername] = nil
	    end

            minetest.chat_send_player(playername, "Code validation succeeded, fediauth login enabled")
        else
            minetest.chat_send_player(playername, "Code validation failed!")
        end

    end
end)