-- luatex-cn-font-autodetect.lua
-- Automatic font detection for Chinese typesetting
-- Similar to ctex's fontset mechanism

local fontdetect = {}

-- Font schemes for different platforms
-- Each font entry is a list of aliases (English and Chinese names) for the same font
-- This allows detection to work regardless of how the font is registered in the system
fontdetect.schemes = {
    -- Windows fonts (中易字体 / 微软雅黑)
    -- Include English, Simplified Chinese, and Traditional Chinese names (fix #35)
    windows = {
        name = "windows",
        fonts = {
            main = {
                { "SimSun", "宋体", "宋體" },
                { "NSimSun", "新宋体", "新宋體" },
                { "Microsoft YaHei", "微软雅黑", "微軟雅黑" },
                { "SimHei", "黑体", "黑體" }
            },
            sans = {
                { "Microsoft YaHei", "微软雅黑", "微軟雅黑" },
                { "SimHei", "黑体", "黑體" }
            },
            kai = {
                { "KaiTi", "楷体", "楷體" },
                { "STKaiti", "华文楷体", "華文楷體" },
                { "SimKai", "楷体_GB2312", "楷體_GB2312" }
            },
            fangsong = {
                { "FangSong", "仿宋", "仿宋" },
                { "STFangsong", "华文仿宋", "華文仿宋" },
                { "SimFang", "仿宋_GB2312" }
            }
        },
        features = "RawFeature={+vert,+vrt2}"
    },

    -- macOS fonts (苹方/华文系列)
    -- Include SC (Simplified) and TC (Traditional) variants
    mac = {
        name = "mac",
        fonts = {
            main = {
                { "Songti SC", "宋体-简", "宋體-簡", "Songti TC", "宋體-繁" },
                { "STSong", "华文宋体", "華文宋體" },
                { "PingFang SC", "苹方-简", "蘋方-簡", "PingFang TC", "蘋方-繁" }
            },
            sans = {
                { "PingFang SC", "苹方-简", "蘋方-簡", "PingFang TC", "蘋方-繁" },
                { "Heiti SC", "黑体-简", "黑體-簡", "Heiti TC", "黑體-繁" },
                { "STHeiti", "华文黑体", "華文黑體" }
            },
            kai = {
                { "Kaiti SC", "楷体-简", "楷體-簡", "Kaiti TC", "楷體-繁" },
                { "STKaiti", "华文楷体", "華文楷體" }
            },
            fangsong = {
                { "STFangsong", "华文仿宋", "華文仿宋" },
                { "FangSong", "仿宋" }
            }
        },
        features = "RawFeature={+vert,+vrt2}"
    },

    -- Linux fonts (Fandol 开源字体)
    fandol = {
        name = "fandol",
        fonts = {
            main = { { "FandolSong-Regular" }, { "FandolSong" } },
            sans = { { "FandolHei-Regular" }, { "FandolHei" } },
            kai = { { "FandolKai-Regular" }, { "FandolKai" } },
            fangsong = { { "FandolFang-Regular" }, { "FandolFang" } }
        },
        features = "RawFeature={+vert,+vrt2}"
    },

    -- Ubuntu fonts (文泉驿/Noto)
    ubuntu = {
        name = "ubuntu",
        fonts = {
            main = {
                { "Noto Serif CJK SC", "Noto Serif CJK TC" },
                { "Source Han Serif SC", "思源宋体", "思源宋體", "Source Han Serif TC" }
            },
            sans = {
                { "Noto Sans CJK SC", "Noto Sans CJK TC" },
                { "Source Han Sans SC", "思源黑体", "思源黑體", "Source Han Sans TC" }
            },
            kai = {
                { "AR PL UKai CN", "AR PL UKai TW" },
                { "WenQuanYi Zen Hei", "文泉驿正黑", "文泉驛正黑" }
            },
            fangsong = {
                { "Noto Serif CJK SC", "Noto Serif CJK TC" },
                { "Source Han Serif SC", "思源宋体", "思源宋體", "Source Han Serif TC" }
            }
        },
        features = "RawFeature={+vert,+vrt2}"
    },

    -- Common alternative fonts (备用方案)
    common = {
        name = "common",
        fonts = {
            main = {
                { "TW-Kai" },
                { "Source Han Serif SC", "思源宋体", "思源宋體", "Source Han Serif TC" },
                { "Noto Serif CJK SC", "Noto Serif CJK TC" }
            },
            sans = {
                { "Source Han Sans SC", "思源黑体", "思源黑體", "Source Han Sans TC" },
                { "Noto Sans CJK SC", "Noto Sans CJK TC" }
            },
            kai = {
                { "TW-Kai" },
                { "AR PL UKai CN", "AR PL UKai TW" }
            },
            fangsong = {
                { "TW-Kai" },
                { "Noto Serif CJK SC", "Noto Serif CJK TC" }
            }
        },
        features = "RawFeature={+vert,+vrt2}"
    }
}

-- Detect operating system
function fontdetect.detect_os()
    local os_type = os.type or "unix"

    -- Check if Windows
    if os_type == "windows" or package.config:sub(1, 1) == '\\' then
        return "windows"
    end

    -- Check if macOS (Darwin)
    local handle = io.popen("uname -s 2>/dev/null")
    if handle then
        local result = handle:read("*a")
        handle:close()
        if result and result:match("Darwin") then
            return "mac"
        end
    end

    -- Assume Linux/Unix
    return "linux"
end

-- Check if a single font name is available
function fontdetect.font_exists(fontname)
    if not fontname or fontname == "" then return false end
    local ok, res = pcall(require, "luaotfload")
    local lotf = (type(res) == "table" and res) or _G.luaotfload
    if ok and type(lotf) == "table" and type(lotf.find_file) == "function" then
        return lotf.find_file(fontname) ~= nil
    end
    -- If we can't check, we return true to let TeX/fontspec handle it later
    return true
end

-- Find font from a list of aliases (English and Chinese names)
-- Returns the first found name, or nil if none found (fix #35)
-- @param font_aliases (table|string) A list of alternative names for the same font
-- @return (string|nil) The first found font name, or nil
function fontdetect.find_any_font(font_aliases)
    if type(font_aliases) == "string" then
        font_aliases = { font_aliases }
    end

    local ok, res = pcall(require, "luaotfload")
    local lotf = (type(res) == "table" and res) or _G.luaotfload

    if not (ok and type(lotf) == "table" and type(lotf.find_file) == "function") then
        -- Can't check, return first name as fallback
        return font_aliases[1]
    end

    for _, name in ipairs(font_aliases) do
        if name and name ~= "" and lotf.find_file(name) then
            return name
        end
    end

    return nil
end

-- Find the first available font from a list of font groups
-- Each group is a table of aliases (English/Chinese names for the same font)
-- @param font_list (table) A list of font groups, e.g. { {"SimSun", "宋体"}, {"NSimSun", "新宋体"} }
-- @return (string|nil) The first found font name
function fontdetect.resolve_font(font_list)
    if type(font_list) == "string" then
        if fontdetect.font_exists(font_list) then return font_list end
        return nil
    end

    for _, entry in ipairs(font_list) do
        local found
        if type(entry) == "table" then
            -- Entry is a list of aliases for one font
            found = fontdetect.find_any_font(entry)
        else
            -- Entry is a single font name
            if fontdetect.font_exists(entry) then
                found = entry
            end
        end
        if found then return found end
    end
    return nil
end

-- Select best available font scheme (now returns the raw scheme with candidate lists)
function fontdetect.auto_select_scheme()
    local os_name = fontdetect.detect_os()
    local scheme = nil

    texio.write_nl("term and log", "[Font Auto-Detect] Operating system detected: " .. os_name)

    if os_name == "windows" then
        scheme = fontdetect.schemes.windows
    elseif os_name == "mac" then
        scheme = fontdetect.schemes.mac
    else
        scheme = fontdetect.schemes.fandol
    end

    if scheme then
        texio.write_nl("term and log", "[Font Auto-Detect] Selected candidate scheme: " .. scheme.name)
    end

    return scheme
end

-- Get font setup information (returns lists as strings)
-- The font list now contains alias groups; we extract the first (primary) name from each
function fontdetect.get_font_setup()
    local scheme = fontdetect.auto_select_scheme()

    if not scheme then return nil end

    -- Extract primary font names from alias groups and join with commas
    local function join_fonts(list)
        if type(list) == "string" then return list end
        local names = {}
        for _, entry in ipairs(list) do
            if type(entry) == "table" then
                -- Entry is an alias group; use the first (English) name
                if entry[1] then
                    table.insert(names, entry[1])
                end
            else
                -- Entry is a single font name
                table.insert(names, entry)
            end
        end
        return table.concat(names, ",")
    end

    return {
        main = join_fonts(scheme.fonts.main),
        sans = join_fonts(scheme.fonts.sans),
        kai = join_fonts(scheme.fonts.kai),
        fangsong = join_fonts(scheme.fonts.fangsong),
        features = scheme.features,
        scheme = scheme.name
    }
end

-- 注册模块到 package.loaded
package.loaded['fonts.luatex-cn-font-autodetect'] = fontdetect

return fontdetect
