-- this is the first file executed when the application starts
-- we have to load the first modules form here

-- =============================================================================
-- VERSION CONFIGURATION - Single source of truth for client versioning
-- Update this value when releasing a new version
-- =============================================================================
APP_VERSION = "1.2.1"
-- =============================================================================

-- =============================================================================
-- SERVICES CONFIGURATION
-- Configure your server URLs here
-- =============================================================================
Services = {
    updater = "https://vexiaonline.cl/api/updater.php",
    status = "https://vexiaonline.cl/login.php", --./client_entergame | ./client_topmenu
    --websites = "https://vexiaonline.cl/?subtopic=accountmanagement", --./client_entergame "Forgot password and/or email"
    --createAccount = "https://vexiaonline.cl/clientcreateaccount.php", --./client_entergame -- createAccount.lua
    --getCoinsUrl = "https://vexiaonline.cl/?subtopic=shop&step=terms", --./game_market
}

-- HARDCODED to Vexia Online production server ONLY
-- This client can ONLY connect to vexiaonline.cl
-- Server/Port/Version fields are HIDDEN from users
Servers_init = {
    ["vexiaonline.cl"] = {
        ["port"] = 7171,
        ["protocol"] = 772,
        ["httpLogin"] = false
    }
}

g_app.setName("Vexia Online");
g_app.setCompactName("vexia-online");
g_app.setOrganizationName("Vexia Online");

g_app.hasUpdater = function()
    return (Services.updater and Services.updater ~= "" and g_modules.getModule("updater"))
end

-- setup logger
g_logger.setLogFile(g_resources.getWorkDir() .. g_app.getCompactName() .. '.log')
g_logger.info(os.date('== application started at %b %d %Y %X'))
g_logger.info("== operating system: " .. g_platform.getOSName())

-- print first terminal message
g_logger.info(g_app.getName() .. ' ' .. g_app.getVersion() .. ' rev ' .. g_app.getBuildRevision() .. ' (' ..
    g_app.getBuildCommit() .. ') built on ' .. g_app.getBuildDate() .. ' for arch ' ..
    g_app.getBuildArch())

-- setup lua debugger
if os.getenv("LOCAL_LUA_DEBUGGER_VSCODE") == "1" then
    require("lldebugger").start()
    g_logger.debug("Started LUA debugger.")
else
    g_logger.debug("LUA debugger not started (not launched with VSCode local-lua).")
end

-- add data directory to the search path
if not g_resources.addSearchPath(g_resources.getWorkDir() .. 'data', true) then
    g_logger.fatal('Unable to add data directory to the search path.')
end

-- add modules directory to the search path
if not g_resources.addSearchPath(g_resources.getWorkDir() .. 'modules', true) then
    g_logger.fatal('Unable to add modules directory to the search path.')
end

g_html.addGlobalStyle('/data/styles/html.css')
g_html.addGlobalStyle('/data/styles/custom.css')

-- try to add mods path too
g_resources.addSearchPath(g_resources.getWorkDir() .. 'mods', true)

-- setup directory for saving configurations
g_resources.setupUserWriteDir(('%s/'):format(g_app.getCompactName()))

-- One-shot migration from the legacy shared "otclient" user directory.
-- Previously we used compactName = "otclient" like every other mehah-based
-- client, so our user data collided with unrelated forks. After renaming to
-- a Vexia-specific dir, existing Vexia players would appear to lose their
-- config / minimap / hotkeys / characterdata. Import it once if we detect
-- the Vexia marker in the legacy config.
local function migrateFromLegacyOtclientDir()
    local SENTINEL_VPATH = '/vexia-migrated.flag'
    if g_resources.fileExists(SENTINEL_VPATH) then return end

    local isWindows = (g_platform.getOsShortName() == 'windows')

    -- PhysFS's PHYSFS_getPrefDir + setupUserWriteDir produce:
    --   Windows: APPDATA\<org>\<compactName>\<compactName>\   (3 segments)
    --   Linux:   $XDG_DATA_HOME/<compactName>/.<compactName>/ (2 segments, org ignored)
    -- The legacy otclient client used org="otcr" / compactName="otclient".
    local candidates = {}
    if isWindows then
        local appdata = os.getenv('APPDATA')
        if appdata and appdata ~= '' then
            if appdata:sub(-1) == '\\' or appdata:sub(-1) == '/' then
                appdata = appdata:sub(1, -2)
            end
            table.insert(candidates, appdata .. '\\otcr\\otclient\\otclient\\')
            -- Secondary fallback in case older PhysFS versions omitted org:
            table.insert(candidates, appdata .. '\\otclient\\otclient\\')
        end
    else
        local home = os.getenv('HOME')
        if home and home ~= '' then
            if home:sub(-1) == '/' then home = home:sub(1, -2) end
            table.insert(candidates, home .. '/.local/share/otclient/.otclient/')
            table.insert(candidates, home .. '/.local/share/otcr/otclient/.otclient/')
        end
    end

    local oldDir
    for _, candidate in ipairs(candidates) do
        if g_platform.fileExists(candidate .. 'config.otml') then
            oldDir = candidate
            break
        end
    end

    local status = 'no-legacy-dir'
    if oldDir then
        local fh = io.open(oldDir .. 'config.otml', 'r')
        if fh then
            local contents = fh:read('*a') or ''
            fh:close()
            if contents:find('vexiaonline.cl', 1, true) then
                local newDir = g_resources.getWriteDir() or ''
                if newDir ~= '' then
                    local nativeSep = isWindows and '\\' or '/'
                    newDir = newDir:gsub('[/\\]+', nativeSep)
                    if newDir:sub(-1) ~= nativeSep then newDir = newDir .. nativeSep end
                    local cmd
                    if isWindows then
                        cmd = 'xcopy /E /I /Y "' .. oldDir .. '*" "' .. newDir .. '" > NUL 2>&1'
                    else
                        cmd = 'cp -rn "' .. oldDir .. '." "' .. newDir .. '" 2>/dev/null'
                    end
                    os.execute(cmd)
                    status = 'imported'
                    g_logger.info('[migration] Imported Vexia Online user data from ' .. oldDir)
                end
            else
                status = 'no-vexia-marker'
            end
        end
    end

    g_resources.writeFileContents(SENTINEL_VPATH,
        'checked on ' .. os.date() .. ' - ' .. status .. '\n')
end
-- migrateFromLegacyOtclientDir() -- disabled: every active player has already been migrated

-- search all packages
g_resources.searchAndAddPackages('/', '.otpkg', true)

-- load settings
g_configs.loadSettings('/config.otml')

g_modules.discoverModules()

-- libraries modules 0-99
g_modules.autoLoadModules(99)
g_modules.ensureModuleLoaded('corelib')
g_modules.ensureModuleLoaded('gamelib')
g_modules.ensureModuleLoaded('modulelib')
g_modules.ensureModuleLoaded("startup")

g_modules.autoLoadModules(999)
g_modules.ensureModuleLoaded('game_shaders') -- pre load

local function loadModules()
    -- client modules 100-499
    g_modules.autoLoadModules(499)
    g_modules.ensureModuleLoaded('client')

    -- game modules 500-999
    g_modules.autoLoadModules(999)
    g_modules.ensureModuleLoaded('game_interface')

    -- mods 1000-9999
    g_modules.autoLoadModules(9999)
    g_modules.ensureModuleLoaded('client_mods')

    local script = '/' .. g_app.getCompactName() .. 'rc.lua'

    if g_resources.fileExists(script) then
        dofile(script)
    end

    -- uncomment the line below so that modules are reloaded when modified. (Note: Use only mod dev)
    -- g_modules.enableAutoReload()
end

-- run updater, must use data.zip
if g_app.hasUpdater() then
    g_modules.ensureModuleLoaded("updater")
    return Updater.init(loadModules)
end

loadModules()
