local export = {}
local lang = require("Module:languages").getByCode("izh")
export.lang = lang

function export.guess_vowel_harmony(word)
	local l = mw.ustring.len(word)
	for i = l, 1, -1 do
		local c = mw.ustring.sub(word, i, i)
		if mw.ustring.match(c, "[aouь]") then
			return "a"
		elseif mw.ustring.match(c, "[äöy]") then
			return "ä"
		end
	end
	return "ä"
end

local consonants = "bcdfghjklmnprsštvzž"
local consonant = "[" .. consonants .. "]"
local vowels = "aeiouyäöь"
local vowel = "[" .. vowels .. "]"

local consonants_geminatable = "bdfghjklmnprsštvzž"

-- orthographic symbols that signify separation of syllables
local virtual_syllable_break = mw.ustring.char(0xE200)
local sep_symbols = "-./ " .. virtual_syllable_break

local diphthongs = {
	"[aeouyäö]i",
	"[aeio]u",
	"[äeiö]y"
}
local vowel_sequences = { unpack(diphthongs) }
local vowel_sequences_additional = {
	"aa", "ee", "ii", "oo", "uu", "yy", "ää", "öö", "ьь"
}
for _, vs in ipairs(vowel_sequences_additional) do
	table.insert(vowel_sequences, vs)
end

export.consonants = consonants
export.consonant = consonant
export.vowels = vowels
export.vowel = vowel
export.consonants_geminatable = consonants_geminatable

export.virtual_syllable_break = virtual_syllable_break
export.sep_symbols = sep_symbols
export.diphthongs = diphthongs
export.vowel_sequences = vowel_sequences

-- adapted from [[Module:fi-hyphenation]]
function export.split_syllables(word)
	local res = {}
	local syllable = ""
	local pos = 1
	local found_vowel = false
	
	while pos <= #word do
		if mw.ustring.find(mw.ustring.lower(word), "^" .. consonant .. vowel, pos) then
			-- CV: end current syllable if we have found a vowel
			if found_vowel then
				if syllable then table.insert(res, syllable) end
				found_vowel = false
				syllable = ""
			end
			syllable = syllable .. mw.ustring.sub(word, pos, pos)
			pos = pos + 1
		elseif mw.ustring.find(mw.ustring.lower(word), "^" .. consonant, pos) then
			-- C: continue
			syllable = syllable .. mw.ustring.sub(word, pos, pos)
			pos = pos + 1
		elseif mw.ustring.find(mw.ustring.lower(word), "^" .. vowel, pos) then
			if found_vowel then
				-- already found a vowel, end current syllable
				if syllable then
					table.insert(res, syllable)
				end
				syllable = ""
			end	
			found_vowel = true
			
			-- check for diphthongs or long vowels
			local seq_ok = false
			for k, v in pairs(vowel_sequences) do
				if mw.ustring.find(mw.ustring.lower(word), "^" .. v, pos) then
					seq_ok = true
					break
				end
			end
			
			if seq_ok then
				syllable = syllable .. mw.ustring.sub(word, pos, pos + 1)
				pos = pos + 2
			else
				syllable = syllable .. mw.ustring.sub(word, pos, pos)
				pos = pos + 1
			end
		elseif mw.ustring.find(mw.ustring.lower(word), "^[" .. sep_symbols .. "]", pos) then
			-- separates syllables
			if syllable then
				table.insert(res, syllable)
			end
			
			local sepchar = mw.ustring.sub(word, pos, pos)
			syllable = ""
			pos = pos + 1
			found_vowel = false
		else
			-- ?: continue
			syllable = syllable .. mw.ustring.sub(word, pos, pos)
			pos = pos + 1
		end
	end
	
	if syllable then
		table.insert(res, syllable)
	end
	
	return res
end

local function make_geminated_stem(word)
	local prefix, fc, fv = mw.ustring.match(word, "(.*)([" .. consonants_geminatable .. "])(" .. vowel .. ")$")
	if not prefix then return nil end
	if mw.ustring.match(prefix, consonant .. "$") then return nil end
	if fc == "j" then
		return prefix .. "i" .. fc
	else
		return prefix .. fc .. fc
	end
end

function export.is_heavy_syllable(syl)
	return mw.ustring.match(syl, consonant .. "$") or mw.ustring.match(syl, vowel .. vowel)
end

function export.guess_gemination(word)
	local syl = export.split_syllables(word)
	if not syl then return nil end
	local n = #syl
	if n < 2 then return nil end
	if n % 2 == 1 then return nil end
	if export.is_heavy_syllable(syl[n - 1]) then return nil end
	return make_geminated_stem(word)
end

function export.guess_elongation(word)
	local syl = export.split_syllables(word)
	if not syl then return nil end
	local n = #syl
	if n < 2 then return true end
	if n % 2 == 1 then return true end
	if export.is_heavy_syllable(syl[n - 1]) then return true end
	return false
end

return export