-- NOTE:
-- xmake cannot accept the global variables in on_xxx functions, so we use a wrapper function to bind it

-- export specified godot project, with the export execution name
-- args:
--  target_platform: the target platform, like "Windows Desktop"
--  name: the export execute name, it will be endswith ".exe" on windows
task("export")
    on_run((function(godot_project_folder, publish_folder, project_name)
        return function(target_platform)
            local name = godot_project_folder
            
            -- different platform may have different execute name
            -- xmake supported platforms:
            -- windows
            -- cross
            -- linux
            -- macosx
            -- android
            -- iphoneos
            -- watchos
            if is_plat("windows") then
                name = name .. ".exe"
            end

            local export_mode = "export-debug"

            if is_mode("release") then
                export_mode = "export-release"
            end

            if not os.isdir(publish_folder) then
                os.mkdir(publish_folder)
            end

            local godot_project_file = path.join(godot_project_folder, "project.godot")

            local export_path = path.absolute(path.join(publish_folder, project_name))

            local cmd = format("godot %s --headless --%s %s %s", godot_project_file, export_mode, "\"" .. target_platform .. "\"", export_path)

            os.execv("echo", {cmd})
            os.exec(cmd)
        end
    
    end)(GODOT_PROJECT_FOLDER, PUBLISH_FOLDER, PROJECT_NAME))
task_end()





-- clean the publish folder and build folder
task("clean-publish")
    on_run((function(godot_project_folder, publish_folder)
        return function ()
            -- remove publish folder
            if os.isdir(publish_folder) then
                os.tryrm(publish_folder)
            end

            -- remove build target folder
            local bin_dir = path.join(godot_project_folder, "bin")
            if os.isdir(bin_dir) then
                os.tryrm(path.join(bin_dir, "$(os)"))
            end
        end
    end)(GODOT_PROJECT_FOLDER, PUBLISH_FOLDER))
task_end()


-- tasks that exposed to cli
-- NOTE: for complex tasks, we can use a seprate file to define it

-- generate a class that inherit from godot class
-- args:
--   name: the new class name
--   basename: the base class name to inherit (must under godot_cpp/classes)
--   dir: the directory to save the class (must under src)
--   namespace: the namespace of the new class

task("ext-class")
    on_run(function ()
        -- more on: https://xmake.io/#/manual/plugin_task
        -- we need this module to load options from menu
        import "core.base.option"

        local namespace = option.get("namespace")
        local name = option.get("name")
        local base = option.get("base")
        local dir = option.get("dir")

        -- we calculate these here, in case there is any special case to handle
        local header_guard = string.upper(name) .. "_H"

        import("class_tpl", {rootdir="templates", alias="class_render"})

        -- header and impl text
        local header_text = class_render.render_header(header_guard, namespace, name, base)
        local impl_text = class_render.render_impl(namespace, name)

        -- save
        local output_dir = "src"

        if dir ~= nil then
            output_dir = path.join("src", dir)
        end

        if not os.isdir(output_dir) then
            os.mkdir(output_dir)
        end

        local header_file = path.join(output_dir, string.lower(name) .. ".h")
        local impl_file = path.join(output_dir, string.lower(name) .. ".cpp")

        io.writefile(header_file, header_text)
        io.writefile(impl_file, impl_text)

    end)

    -- options 
    set_menu {
        usage = "xmake ext-class [options]",

        description = "Generate godot class that inherits from a base class under godot_cpp/classes",

        options = {

            -- kv options
            -- (short, long), (kv, default_value), description, [values])
            {"s", "namespace",    "kv", "godot",  "Set the namespace of the new class"},
            {"d", "dir",          "kv", nil,      "Set the directory to save the class"},

            {},

            -- single value options
            {"n", "name",         "v", nil,       "Set the new class name"},
            {"b", "base",         "v", nil,       "Set the base class name to inherit"},
        }
    }
task_end() 





task("gengdextension")
    on_run((function(godot_project_folder, project_name)
        return function ()

            local bin_dir = path.join(godot_project_folder, "bin")
            if not os.isdir(bin_dir) then
                os.mkdir(bin_dir)
            end
            
            local godot_gdextension_file = path.join(bin_dir, project_name .. ".gdextension")

            local fileContent = 
[[
[icons]
ProjectName = "res://icon.svg"

[configuration]

entry_symbol = "library_init"
compatibility_minimum = "4.2"

[libraries]

macos.debug = "res://lib/libProjectName.macos_framework"
macos.release = "res://lib/libProjectName.macos_framework"

window.debug.x86_32 = "res://lib/libProjectName.windows_debug_x86.dll"
window.release.x86_32 = "res://lib/libProjectName.windows_release_x86.dll"
window.debug.x86_64 = "res://lib/libProjectName.windows_debug_x64.dll"
window.release.x86_64 = "res://lib/libProjectName.windows_release_x64.dll"

linux.debug.x86_64 = "res://lib/libProjectName.linux_debug_x86_64.so"
linux.release.x86_64 = "res://lib/libProjectName.linux_release_x86_64.so"
linux.debug.arm64 = "res://lib/libProjectName.linux_debug_arm64.so"
linux.release.arm64 = "res://lib/libProjectName.linux_release_arm64.so"
linux.debug.rv64 = "res://lib/libProjectName.linux_debug_rv64.so"
linux.release.rv64 = "res://lib/libProjectName.linux_release_rv64.so"

android.debug.x86_64 = "res://lib/libProjectName.android_debug_x86_64.so"
android.release.x86_64 = "res://lib/libProjectName.android_release_x86_64.so"
android.debug.arm64 = "res://lib/libProjectName.android_debug_arm64.so"
android.release.arm64 = "res://lib/libProjectName.android_release_arm64.so"

]]

            -- needs testing with macos

            fileContent = string.gsub(fileContent, "ProjectName", project_name)

            io.writefile(godot_gdextension_file, fileContent)
        end
    end)(GODOT_PROJECT_FOLDER, PROJECT_NAME))

    -- options 
    set_menu {
        usage = "xmake gengdextension",

        description = "Generate gdextension file",
    }
task_end()


task("import-assets")
    on_run((function(godot_project_folder, project_name)
        return function ()
            local godot_project_file = path.join(godot_project_folder, "project.godot")

            local cmd = format("godot --headless --import %s", godot_project_file)
            os.execv("echo", {cmd})
            os.exec(cmd)
        end
    end)(GODOT_PROJECT_FOLDER, PROJECT_NAME))

    set_menu {
        usage = "xmake import-assets",

        description = "Import project assets",
    }
task_end()