-- deinflection rules (ordered by appearance in tae kim's japanese grammar guide)
create temporary table deinflection_temp (tag, kana_in, kana_out, rules_in, rules_out);
insert into deinflection_temp values
	-- negative <https://guidetojapanese.org/learn/grammar/negativeverbs>
	('infl:negative',   'ない', 'る', 'a', 'ru'),
	('infl:negative', 'わない', 'う', 'a', 'u'),
	('infl:negative', 'かない', 'く', 'a', 'u'),
	('infl:negative', 'がない', 'ぐ', 'a', 'u'),
	('infl:negative', 'さない', 'す', 'a', 'u'),
	('infl:negative', 'たない', 'つ', 'a', 'u'),
	('infl:negative', 'なない', 'ぬ', 'a', 'u'),
	('infl:negative', 'ばない', 'ぶ', 'a', 'u'),
	('infl:negative', 'まない', 'む', 'a', 'u'),
	('infl:negative', 'らない', 'る', 'a', 'u'),
	('infl:negative', 'しない', 'する', 'a', 's'),
	('infl:negative', 'こない', 'くる', 'a', 'k'),
	('infl:negative', '来ない', '来る', 'a', 'k'),
	-- ('infl:negative',   'ない', 'ある', 'a', 'ru'), -- this one may cause problems (?)
	-- ('infl:negative',   'ない', '', 'a', 'ru'), -- this one may cause problems (?)

	-- past tense <https://guidetojapanese.org/learn/grammar/past_tense>
	('infl:tense:past',   'た', 'る', 'a', 'ru'),
	('infl:tense:past', 'した', 'す', 'a', 'u'),
	('infl:tense:past', 'いた', 'く', 'a', 'u'),
	('infl:tense:past', 'いだ', 'ぐ', 'a', 'u'),
	('infl:tense:past', 'んだ', 'む', 'a', 'u'),
	('infl:tense:past', 'んだ', 'ぬ', 'a', 'u'),
	('infl:tense:past', 'んだ', 'ぶ', 'a', 'u'),
	('infl:tense:past', 'った', 'う', 'a', 'u'),
	('infl:tense:past', 'った', 'つ', 'a', 'u'),
	('infl:tense:past', 'った', 'る', 'a', 'u'),
	('infl:tense:past', 'した', 'する', 'a', 's'),
	('infl:tense:past', 'きた', 'くる', 'a', 'k'),
	('infl:tense:past', '来た', 'くる', 'a', 'k'),
	('infl:tense:past', '行った', '行く', 'a', ''),
	('infl:tense:past', 'かった', 'い', 'a', 'a'), -- past negative

	-- adjective to adverb <https://guidetojapanese.org/learn/grammar/adverbs>
	('infl:adverb', 'く', 'い', 'a', 'i'),
	-- TODO: na-adjectives aren't deconjugated

	-- polite form <https://guidetojapanese.org/learn/grammar/polite>
	('infl:polite:masu',   'ます', 'る', 'a', 'ru'),
	('infl:polite:masu', 'います', 'う', 'a', 'u'),
	('infl:polite:masu', 'きます', 'く', 'a', 'u'),
	('infl:polite:masu', 'ぎます', 'ぐ', 'a', 'u'),
	('infl:polite:masu', 'します', 'す', 'a', 'u'),
	('infl:polite:masu', 'ちます', 'つ', 'a', 'u'),
	('infl:polite:masu', 'にます', 'ぬ', 'a', 'u'),
	('infl:polite:masu', 'びます', 'ぶ', 'a', 'u'),
	('infl:polite:masu', 'みます', 'む', 'a', 'u'),
	('infl:polite:masu', 'ります', 'る', 'a', 'u'),
	('infl:polite:masu', 'します', 'する', 'a', 's'),
	('infl:polite:masu', 'きます', 'くる', 'a', 'k'),
	('infl:polite:masu', '来ます', '来る', 'a', 'k'),
	('infl:polite:masu infl:negative',   'ません', 'る', 'a', 'ru'),
	('infl:polite:masu infl:negative', 'いません', 'う', 'a', 'u'),
	('infl:polite:masu infl:negative', 'きません', 'く', 'a', 'u'),
	('infl:polite:masu infl:negative', 'ぎません', 'ぐ', 'a', 'u'),
	('infl:polite:masu infl:negative', 'しません', 'す', 'a', 'u'),
	('infl:polite:masu infl:negative', 'ちません', 'つ', 'a', 'u'),
	('infl:polite:masu infl:negative', 'にません', 'ぬ', 'a', 'u'),
	('infl:polite:masu infl:negative', 'びません', 'ぶ', 'a', 'u'),
	('infl:polite:masu infl:negative', 'みません', 'む', 'a', 'u'),
	('infl:polite:masu infl:negative', 'りません', 'る', 'a', 'u'),
	('infl:polite:masu infl:negative', 'しません', 'する', 'a', 's'),
	('infl:polite:masu infl:negative', 'きません', 'くる', 'a', 'k'),
	('infl:polite:masu infl:negative', '来ません', '来る', 'a', 'k'),
	('infl:polite:masu infl:tense:past',   'ました', 'る', 'a', 'ru'),
	('infl:polite:masu infl:tense:past', 'いました', 'う', 'a', 'u'),
	('infl:polite:masu infl:tense:past', 'きました', 'く', 'a', 'u'),
	('infl:polite:masu infl:tense:past', 'ぎました', 'ぐ', 'a', 'u'),
	('infl:polite:masu infl:tense:past', 'しました', 'す', 'a', 'u'),
	('infl:polite:masu infl:tense:past', 'ちました', 'つ', 'a', 'u'),
	('infl:polite:masu infl:tense:past', 'にました', 'ぬ', 'a', 'u'),
	('infl:polite:masu infl:tense:past', 'びました', 'ぶ', 'a', 'u'),
	('infl:polite:masu infl:tense:past', 'みました', 'む', 'a', 'u'),
	('infl:polite:masu infl:tense:past', 'りました', 'る', 'a', 'u'),
	('infl:polite:masu infl:tense:past', 'しました', 'する', 'a', 's'),
	('infl:polite:masu infl:tense:past', 'きました', 'くる', 'a', 'k'),
	('infl:polite:masu infl:tense:past', '来ました', '来る', 'a', 'k'),
	('infl:polite:masu infl:tense:past infl:negative',   'ませんでした', 'る', 'a', 'ru'),
	('infl:polite:masu infl:tense:past infl:negative', 'いませんでした', 'う', 'a', 'u'),
	('infl:polite:masu infl:tense:past infl:negative', 'きませんでした', 'く', 'a', 'u'),
	('infl:polite:masu infl:tense:past infl:negative', 'ぎませんでした', 'ぐ', 'a', 'u'),
	('infl:polite:masu infl:tense:past infl:negative', 'しませんでした', 'す', 'a', 'u'),
	('infl:polite:masu infl:tense:past infl:negative', 'ちませんでした', 'つ', 'a', 'u'),
	('infl:polite:masu infl:tense:past infl:negative', 'にませんでした', 'ぬ', 'a', 'u'),
	('infl:polite:masu infl:tense:past infl:negative', 'びませんでした', 'ぶ', 'a', 'u'),
	('infl:polite:masu infl:tense:past infl:negative', 'みませんでした', 'む', 'a', 'u'),
	('infl:polite:masu infl:tense:past infl:negative', 'りませんでした', 'る', 'a', 'u'),
	('infl:polite:masu infl:tense:past infl:negative', 'しませんでした', 'する', 'a', 's'),
	('infl:polite:masu infl:tense:past infl:negative', 'きませんでした', 'くる', 'a', 'k'),
	('infl:polite:masu infl:tense:past infl:negative', '来ませんでした', '来る', 'a', 'k'),
	-- ('infl:polite:masu infl:tense:past infl:negative', 'くありません', 'い', 'a', 'i'), -- reality check (should not be needed)

	-- TODO: compound nouns and adjectives <https://guidetojapanese.org/learn/grammar/compound>

	-- te-form <https://guidetojapanese.org/learn/grammar/compound>
	('infl:suffix:te',   'て',   'た', 'a', 'ru'),
	('infl:suffix:te', 'して', 'した', 'a', 's u'),
	('infl:suffix:te', 'いて', 'いた', 'a', 'u'),
	('infl:suffix:te', 'いで', 'いだ', 'a', 'u'),
	('infl:suffix:te', 'んで', 'んだ', 'a', 'u'),
	('infl:suffix:te', 'って', 'った', 'a', 'u'),
	('infl:suffix:te', 'きて', 'きた', 'a', 'k'),
	('infl:suffix:te', '来て', '来た', 'a', 'k'),
	('infl:suffix:te', 'くて', 'い', 'a', 'a'),
	('infl:suffix:te', 'よくて', 'いい', 'a', 'a'), -- exception

	-- -tari lists <https://guidetojapanese.org/learn/grammar/compound>
	('infl:suffix:tari',   'たり',   'た', 'a', 'ru'),
	('infl:suffix:tari', 'したり', 'した', 'a', 's u'),
	('infl:suffix:tari', 'いたり', 'いた', 'a', 'u'),
	('infl:suffix:tari', 'いだり', 'いだ', 'a', 'u'),
	('infl:suffix:tari', 'んだり', 'んだ', 'a', 'u'),
	('infl:suffix:tari', 'ったり', 'った', 'a', 'u'),
	('infl:suffix:tari', 'きたり', 'きた', 'a', 'k'),
	('infl:suffix:tari', '来たり', '来た', 'a', 'k'),

	-- -sa (adjective->noun) <https://guidetojapanese.org/learn/grammar/amount>
	('infl:suffix:sa class:noun', 'さ', '', 'a', 'na'),
	('infl:suffix:sa class:noun', 'さ', 'い', 'a', 'i'),

	-- continuous tense <https://guidetojapanese.org/learn/grammar/teform>
	('infl:tense:cont', 'いる', '', 'a', 'a'),

	-- potential form <https://guidetojapanese.org/learn/grammar/potential>
	('infl:potential', 'られる', 'る', 'ru', 'ru'),
	('infl:potential', 'える', 'う', 'ru', 'u'),
	('infl:potential', 'ける', 'く', 'ru', 'u'),
	('infl:potential', 'げる', 'ぐ', 'ru', 'u'),
	('infl:potential', 'せる', 'す', 'ru', 'u'),
	('infl:potential', 'てる', 'つ', 'ru', 'u'),
	('infl:potential', 'ねる', 'ぬ', 'ru', 'u'),
	('infl:potential', 'べる', 'ぶ', 'ru', 'u'),
	('infl:potential', 'める', 'む', 'ru', 'u'),
	('infl:potential', 'れる', 'る', 'ru', 'u'),
	('infl:potential', 'できる', 'する', 'ru', 's'),
	('infl:potential', 'こられる', 'くる', 'ru', 'k'),
	('infl:potential', 'ありうる', 'ある', 'ru', ''), -- exception
	('infl:potential', 'ありえる', 'ある', 'ru', ''), -- exception

	-- conditionals <https://guidetojapanese.org/learn/grammar/conditionals>
	('infl:cond:ba',   'えば', 'う', 'a', 'u'),
	('infl:cond:ba',   'けば', 'く', 'a', 'u'),
	('infl:cond:ba',   'げば', 'ぐ', 'a', 'u'),
	('infl:cond:ba',   'せば', 'す', 'a', 'u'),
	('infl:cond:ba',   'てば', 'つ', 'a', 'u'),
	('infl:cond:ba',   'ねば', 'ぬ', 'a', 'u'),
	('infl:cond:ba',   'べば', 'ぶ', 'a', 'u'),
	('infl:cond:ba',   'めば', 'む', 'a', 'u'),
	('infl:cond:ba',   'れば', 'る', 'a', 'u ru'),
	('infl:cond:ba', 'ければ', 'い', 'a', 'a'),
	-- TODO: 〜であれば (deconjugates to です i think?)
	('infl:cond:ra', 'ら', '', 'a', 'a'), -- TODO: constrain valid matches to after past conjugation?

	-- obligation <https://guidetojapanese.org/learn/grammar/must>
  -- TODO: manually write these out instead of splitting particle and suffix
	('infl:negative infl:must tmp:infl:must:res', 'だめ', '', 'a', 'ot'), -- built-in negative because だめ can't be deconjugated
	('infl:negative infl:must tmp:infl:must:res', 'ダメ', '', 'a', 'ot'), -- same as above but for katakana
	('infl:must tmp:infl:must:res', 'いける', '', 'ru', 'ot'), -- はいけない -> positive (stored this way because obligatory could be in past)
	('infl:must tmp:infl:must:res', 'なる', '', 'u', 'ot'), -- はならない -> positive
	('tmp:infl:must:prt infl:must', 'は', '', 'ot', 'nt'), -- removes particle (negative -te + は + だめ／いけない／ならない)
	('tmp:infl:must:prt infl:must', 'と', '', 'ot', 'nt'), -- removes particle (negative + と + だめ／いけない／ならない)
	-- ('infl:must', 'ば', 'ば', 'ot', 'a'), -- causes infinite loop
	('infl:must tmp:infl:must:prt', 'なくちゃ', 'なくて', 'a', 'a'), -- colloquial abbreviation
	('infl:must tmp:infl:must:prt', 'なきゃ', 'なければ', 'a', 'a'), -- colloquial abbreviation
	('tmp:infl:must:prt', 'ちゃ', 'ては', 'a', 'a'), -- colloquial abbreviation
	('tmp:infl:must:prt', 'じゃ', 'では', 'a', 'a'), -- colloquial abbreviation

	-- ~tai endings <https://guidetojapanese.org/learn/grammar/desire>
	('infl:desire:itai',   'たい', 'る', 'i', 'ru'),
	('infl:desire:itai', 'いたい', 'う', 'i', 'u'),
	('infl:desire:itai', 'きたい', 'く', 'i', 'u'),
	('infl:desire:itai', 'ぎたい', 'ぐ', 'i', 'u'),
	('infl:desire:itai', 'したい', 'す', 'i', 'u'),
	('infl:desire:itai', 'ちたい', 'つ', 'i', 'u'),
	('infl:desire:itai', 'にたい', 'ぬ', 'i', 'u'),
	('infl:desire:itai', 'びたい', 'ぶ', 'i', 'u'),
	('infl:desire:itai', 'みたい', 'む', 'i', 'u'),
	('infl:desire:itai', 'りたい', 'る', 'i', 'u'),
	('infl:desire:itai', 'したい', 'する', 'i', 's'),
	('infl:desire:itai', 'きたい', 'くる', 'i', 'k'),
	('infl:desire:itai', '来たい', '来る', 'i', 'k'),

	-- volitional form <https://guidetojapanese.org/learn/grammar/desire>
	('infl:desire:volitional',   'よう',   'る', 'a', 'ru'),
	('infl:desire:volitional',   'おう',   'う', 'a', 'u'),
	('infl:desire:volitional',   'こう',   'く', 'a', 'u'),
	('infl:desire:volitional',   'ごう',   'ぐ', 'a', 'u'),
	('infl:desire:volitional',   'そう',   'す', 'a', 'u'),
	('infl:desire:volitional',   'とう',   'つ', 'a', 'u'),
	('infl:desire:volitional',   'のう',   'ぬ', 'a', 'u'),
	('infl:desire:volitional',   'ぼう',   'ぶ', 'a', 'u'),
	('infl:desire:volitional',   'もう',   'む', 'a', 'u'),
	('infl:desire:volitional',   'ろう',   'る', 'a', 'u'),
	('infl:desire:volitional', 'しよう', 'する', 'a', 's'),
	('infl:desire:volitional', 'こよう', 'くる', 'a', 'k'),
	('infl:desire:volitional', '来よう', '来る', 'a', 'k'),

	-- polite volitional <https://guidetojapanese.org/learn/grammar/desire>
	('infl:desire:volitional', 'ましょう', 'ます', 'nt', 'nt'),

	-- TODO: making suggestions using the 「ば」 or 「たら」 conditional

	-- attempt (〜みる) <https://guidetojapanese.org/learn/grammar/try>
	('infl:attempt:miru', 'みる', '', 'ru', 'a'),

	-- attempt (〜とする) <https://guidetojapanese.org/learn/grammar/try>
	('infl:attempt:tosuru', 'とする', '', 's', 'a'),

	-- polite requests (〜なさい) <https://guidetojapanese.org/learn/grammar/requests>
	('infl:polite:nasai',   'なさい', 'る', 'a', 'ru'),
	('infl:polite:nasai', 'いなさい', 'う', 'a', 'u'),
	('infl:polite:nasai', 'きなさい', 'く', 'a', 'u'),
	('infl:polite:nasai', 'ぎなさい', 'ぐ', 'a', 'u'),
	('infl:polite:nasai', 'しなさい', 'す', 'a', 'u'),
	('infl:polite:nasai', 'ちなさい', 'つ', 'a', 'u'),
	('infl:polite:nasai', 'になさい', 'ぬ', 'a', 'u'),
	('infl:polite:nasai', 'びなさい', 'ぶ', 'a', 'u'),
	('infl:polite:nasai', 'みなさい', 'む', 'a', 'u'),
	('infl:polite:nasai', 'りなさい', 'る', 'a', 'u'),
	('infl:polite:nasai', 'しなさい', 'する', 'a', 's'),
	('infl:polite:nasai', 'きなさい', 'くる', 'a', 'k'),
	('infl:polite:nasai', '来なさい', '来る', 'a', 'k'),

	-- command form <https://guidetojapanese.org/learn/grammar/requests>
	('infl:command', 'ろ', 'る', 'a', 'ru'),
	('infl:command', 'え', 'う', 'a', 'u'),
	('infl:command', 'け', 'く', 'a', 'u'),
	('infl:command', 'げ', 'ぐ', 'a', 'u'),
	('infl:command', 'せ', 'す', 'a', 'u'),
	('infl:command', 'て', 'つ', 'a', 'u'),
	('infl:command', 'ね', 'ぬ', 'a', 'u'),
	('infl:command', 'れ', 'ぶ', 'a', 'u'),
	('infl:command', 'め', 'む', 'a', 'u'),
	('infl:command', 'れ', 'る', 'a', 'u'),
	('infl:command', 'しろ', 'する', 'a', 's'),
	('infl:command', 'こい', 'くる', 'a', 'k'),
	('infl:command', '来い', '来る', 'a', 'k'),
	('infl:command', 'くれ', 'くれる', 'a', 'ru'), -- TODO: special class?
	('infl:command', '呉れ', '呉れる', 'a', 'ru'), -- TODO: special class?
	('infl:command infl:negative', 'な', '', 'a', 'a'),

	-- causative <https://guidetojapanese.org/learn/grammar/causepass>
	('infl:causative', 'させる', 'る', 'a', 'ru'),
	('infl:causative', 'わせる', 'う', 'a', 'u'),
	('infl:causative', 'かせる', 'く', 'a', 'u'),
	('infl:causative', 'がせる', 'ぐ', 'a', 'u'),
	('infl:causative', 'させる', 'す', 'a', 'u'),
	('infl:causative', 'たせる', 'つ', 'a', 'u'),
	('infl:causative', 'なせる', 'ぬ', 'a', 'u'),
	('infl:causative', 'ばせる', 'ぶ', 'a', 'u'),
	('infl:causative', 'ませる', 'む', 'a', 'u'),
	('infl:causative', 'らせる', 'る', 'a', 'u'),
	('infl:causative', 'させる', 'する', 'a', 's'),
	('infl:causative', 'こさせる', 'くる', 'a', 'k'),
	('infl:causative', '来させる', '来る', 'a', 'k'),
	-- shortened causative
	('infl:causative', 'さす', 'る', 'a', 'ru'),
	('infl:causative', 'わす', 'う', 'a', 'u'),
	('infl:causative', 'かす', 'く', 'a', 'u'),
	('infl:causative', 'がす', 'ぐ', 'a', 'u'),
	('infl:causative', 'さす', 'す', 'a', 'u'),
	('infl:causative', 'たす', 'つ', 'a', 'u'),
	('infl:causative', 'なす', 'ぬ', 'a', 'u'),
	('infl:causative', 'ばす', 'ぶ', 'a', 'u'),
	('infl:causative', 'ます', 'む', 'a', 'u'),
	('infl:causative', 'らす', 'る', 'a', 'u'),
	('infl:causative', 'さす', 'する', 'a', 's'),
	('infl:causative', 'こさす', 'くる', 'a', 'k'),
	('infl:causative', '来さす', '来る', 'a', 'k'),

	-- passive <https://guidetojapanese.org/learn/grammar/causepass>
	('infl:passive', 'られる', 'る', 'ru', 'ru u'),
	('infl:passive', 'われる', 'う', 'ru', 'u'),
	('infl:passive', 'かれる', 'く', 'ru', 'u'),
	('infl:passive', 'がれる', 'ぐ', 'ru', 'u'),
	('infl:passive', 'される', 'す', 'ru', 'u'),
	('infl:passive', 'たれる', 'つ', 'ru', 'u'),
	('infl:passive', 'なれる', 'ぬ', 'ru', 'u'),
	('infl:passive', 'ばれる', 'ぶ', 'ru', 'u'),
	('infl:passive', 'まれる', 'む', 'ru', 'u'),
	('infl:passive', 'される', 'する', 'ru', 's'),
	('infl:passive', 'こられる', 'くる', 'ru', 'k'),
	('infl:passive', '来られる', '来る', 'ru', 'k'),

	-- suru verbs <https://guidetojapanese.org/learn/grammar/surunaru>
	('infl:suru', 'する', '', 's', ''); -- deconjugate suru verbs into stem

-- rule/bitmask lookup table
create temporary table rule_map (tag, name, mask);
insert into rule_map values
	(null,                 'a',   -1    ), -- all      (allow all rules in)
	(null,                 '',    0     ), --          (nothing)
	('infl:reason:ru',     'ru',  1 << 0), -- 一段活用 (ichidan a.k.a. ru-verbs in tae kim's japanese grammar guide)
	('infl:reason:u',      'u',   1 << 1), -- 五段活用 (godan a.k.a. u-verbs in tae kim's japanese grammar guide)
	('infl:reason:suru',   's',   1 << 2), -- する     (suru)
	('infl:reason:kuru',   'k',   1 << 3), -- くる     (kuru)
	(null,                 'z',   1 << 4), -- ずる     (zuru)
	('infl:reason:adj:i',  'i',   1 << 5), -- 形容詞   (i-adjective)
	(null,                 'iru', 1 << 6), -- 〜いる   (temporary iru for progressive tense)
	('infl:reason:adj:na', 'na',  1 << 7), -- 形容動詞 (na-adjective)
	(null,                 'ot',  1 << 8), --          (temporary rule for deconjugating obligatory endings)
	(null,                 'nt',  (1 << 6) - 1); --    (utility no temp, allows anything but temporaries)

-- add tags to db
insert into deinflection_rules (mask, tag)
select mask, tag
from rule_map
where tag is not null;

-- convert space-separated strings to bitmasks and insert into deinflection table
insert into deinflection (tag, kana_in, kana_out, rules_in, rules_out)
with temp_deinflection_map(tag, kana_in, kana_out, rules_in_stack, rules_in, rules_out_stack, rules_out) as (
	select
		tag,
		kana_in,
		kana_out,
		rules_in || ' ',
		'',
		rules_out || ' ',
		''
	from deinflection_temp
	union
	select
		tag,
		kana_in,
		kana_out,
		substr(rules_in_stack, instr(rules_in_stack, ' ') + 1),
		replace(substr(rules_in_stack, 0, instr(rules_in_stack, ' ')), ' ', ''),
		substr(rules_out_stack, instr(rules_out_stack, ' ') + 1),
		replace(substr(rules_out_stack, 0, instr(rules_out_stack, ' ')), ' ', '')
	from temp_deinflection_map
	where
		(length(rules_in_stack) > 1) or
		(length(rules_out_stack) > 1)
)
select
	temp_deinflection_map.tag,
	temp_deinflection_map.kana_in,
	temp_deinflection_map.kana_out,
	-- NOTE: sum() should really be bitwise and across all rows after group by
	-- here. be careful to not specify rules more than once in these columns, or
	-- any other rule if the column has 'a'.
	sum(rule_map_in.mask) as rules_in,
	sum(rule_map_out.mask) as rules_out
from temp_deinflection_map
join rule_map as rule_map_in on rule_map_in.name = temp_deinflection_map.rules_in
join rule_map as rule_map_out on rule_map_out.name = temp_deinflection_map.rules_out
group by
	temp_deinflection_map.tag,
	temp_deinflection_map.kana_in,
	temp_deinflection_map.kana_out;

