local export = {}

local m_IPA = require("Module:IPA")
local lang = require("Module:languages").getByCode("rsk")
local rsub = mw.ustring.gsub
local rlower = mw.ustring.lower
local rmatch = mw.ustring.gmatch
local rfind = mw.ustring.find
local rlast = require("Module:string/replace last").replace_last

local phon = {
	["а"]="a",	["б"]="b",	["в"]="v",	["г"]="ɦ",	["ґ"]="ɡ",
	["д"]="d",	["е"]="ɛ",	["є"]="jɛ",	["ж"]="ʒ",	["з"]="z",
	["и"]="i",	["ї"]="ji",	["к"]="k",	["л"]="l",	["м"]="m",
	["н"]="n",	["о"]="ɔ",	["п"]="p",	["р"]="r",	["с"]="s",
	["т"]="t",	["у"]="u",	["ф"]="f",	["х"]="x",	["ц"]="ts",
	["ч"]="tʃ",	["ш"]="ʃ",	["щ"]="ʃtʃ",["ю"]="ju",	["я"]="ja",
	["ь"]="ʲ",	["й"]="j",
}

local function phonetic(text)
	
	text = rsub(text, " | ", "# | #")
	text = "##" .. rsub(text, " ", "# #") .. "##"
	
	text = rlower(text)
	-- general phonology
	text = rsub(text, "тш", "чш")
	text = rsub(text, "тс", "цс")
	text = rsub(text, ".", phon)
	-- palatalisation
	text = rsub(text, "([dtln])j([aɛiɔu])", "%1ʲ%2")
	-- voicing assimilation
	local i = 0
	text = rsub(text, "b#", "p#")
	text = rsub(text, "v#", "f#")
	text = rsub(text, "d(ʲ?)#", "t%1#")
	text = rsub(text, "z#", "s#")
	text = rsub(text, "ʒ#", "ʃ#")
	text = rsub(text, "ɡ#", "k#")
	text = rsub(text, "ɦ#", "x#")
	while i <= 5 do
		text = rsub(text, "b(# #)?([pftsʃkx])", "p%1%2")
		text = rsub(text, "v(# #)?([pftsʃkx])", "f%1%2")
		text = rsub(text, "d(# #)?([pftsʃkx])", "t%1%2")
		text = rsub(text, "z(# #)?([pftsʃkx])", "s%1%2")
		text = rsub(text, "ʒ(# #)?([pftsʃkx])", "ʃ%1%2")
		text = rsub(text, "ɡ(# #)?([pftsʃkx])", "k%1%2")
		text = rsub(text, "ɦ(# #)?([pftsʃkx])", "x%1%2")
		text = rsub(text, "p(# #)?([bdzʒɡ])", "b%1%2")
		text = rsub(text, "f(# #)?([bdzʒɡ])", "v%1%2")
		text = rsub(text, "t(# #)?([bdzʒɡ])", "d%1%2")
		text = rsub(text, "s(# #)?([bdzʒɡ])", "z%1%2")
		text = rsub(text, "ʃ(# #)?([bdzʒɡ])", "ʒ%1%2")
		text = rsub(text, "k(# #)?([bdzʒɡ])", "ɡ%1%2")
		text = rsub(text, "x(# #)?([bdzʒɡ])", "ɦ%1%2")
		i = i + 1
	end
	-- palatalisation
	text = rsub(text, "([dt])([ln])ʲ", "%1ʲ%2ʲ")
	text = rsub(text, "lnʲ", "lʲnʲ")
	text = rsub(text, "n([dt])ʲ", "nʲ%1ʲ")
	text = rsub(text, "n([dt])([ʃʒ])", "nʲ%1%2")
	text = rsub(text, "dʲ", "ɟ")
	text = rsub(text, "tʲ", "c")
	text = rsub(text, "lʲ", "ʎ")
	text = rsub(text, "nʲ", "ɲ")
	text = rsub(text, "ʲ", "")
	
	local function splitString(text)
	    local items = {}
	    for item in rmatch(text, "#([^#]+)#") do
	        table.insert(items, item)
	    end
	    return items
	end
	
	local function applyStress(items)
	    local processedItems = {}
	    for _, item in ipairs(items) do
	    	item = rlast(item, "([aɛiɔu])", "X%1", 1)
			item = rsub(item, "Xa", "A")
			item = rsub(item, "Xɛ", "E")
			item = rsub(item, "Xi", "I")
			item = rsub(item, "Xɔ", "O")
			item = rsub(item, "Xu", "U")
			item = rlast(item, "([aɛiɔu])", "ˈ%1", 1)
			item = rsub(item, "A", "a")
			item = rsub(item, "E", "ɛ")
			item = rsub(item, "I", "i")
			item = rsub(item, "O", "ɔ")
			item = rsub(item, "U", "u")
			item = rsub(item, "([bvɡdʒzjklmnprstfxɦʃɟcʎɲ])ˈ", "ˈ%1")
			item = rsub(item, "tˈ([sʃ])", "ˈt%1")
			item = rsub(item, "dˈ([zʒ])", "ˈd%1")
			item = rsub(item, "([sʃ])ˈ([pktcfx])", "ˈ%1%2")
			item = rsub(item, "([zʒ])ˈ([bɡdɟvɦ])", "ˈ%1%2")
			item = rsub(item, "([ptckbdɟɡ])ˈ([mnɲlʎrj])", "ˈ%1%2")
			item = rsub(item, "#([bvɡdʒzjklmnprstfxɦʃɟcʎɲ][bvɡdʒzjklmnprstfxɦʃɟcʎɲ]?[bvɡdʒzjklmnprstfxɦʃɟcʎɲ]?)ˈ", "#ˈ%1")
			item = rsub(item, "^([bvɡdʒzjklmnprstfxɦʃɟcʎɲ][bvɡdʒzjklmnprstfxɦʃɟcʎɲ]?[bvɡdʒzjklmnprstfxɦʃɟcʎɲ]?)ˈ", "#ˈ%1")
			if not rfind(item, "ˈ", 1, true) then
		        item = "ˈ" .. item
		    end
			
	        table.insert(processedItems, item)
	    end
	    return processedItems
	end
	
	local function concatIndividualWords(items)
	    local result = "#"
	    for i, item in ipairs(items) do
	        result = result .. item .. "#"
	        if i < #items then
	            result = result .. " #"
	        end
	    end
	    return result
	end

	-- stress
	local items = splitString(text)
	
	local words = applyStress(items)
	
	text = "#" .. concatIndividualWords(words) .. "#"
	
	-- affricates
	text = rsub(text, "tʃ", "t͡ʃ")
	text = rsub(text, "dʒ", "d͡ʒ")
	text = rsub(text, "ts", "t͡s")
	text = rsub(text, "dz", "d͡z")
	-- final substitutions
	text = rsub(text, "'", "")
	text = rsub(text, "n([kɡ])", "ŋ%1")
	
	text = rsub(text, "#", "")
	
	return text
end

function export.IPA(frame)
	local words = {}
	
	for _, word in ipairs(frame:getParent().args) do
		table.insert(words, word)
	end
	
	if #words == 0 then
		words = {mw.title.getCurrentTitle().text}
	end
	
	local IPA_results = {}
	
	for _, word in ipairs(words) do
		table.insert(IPA_results, { pron = "[" .. phonetic(word) .. "]" })
	end
	
	return m_IPA.format_IPA_full { lang = lang, items = IPA_results }
end

return export