--
-- vstudio_slnx.lua
-- Generate a Visual Studio 2026+ solution.
--

premake.vstudio.slnx = {}
local vstudio = premake.vstudio
local slnx = premake.vstudio.slnx


function slnx.generate(sln)
    io.eol = '\r\n'

    -- Precompute Visual Studio configurations
    sln.vstudio_configs = premake.vstudio.buildconfigs(sln)
    -- Prepare imported projects
    premake.vstudio.bakeimports(sln)

    -- Mark the file as Unicode
    _p('\239\187\191')

    -- Write out solution file
    _p('<!-- Generated by GENie https://github.com/bkaradzic/GENie -->')
    _p('<Solution>')
    slnx.configurations(sln)
    for group in premake.solution.eachgroup(sln) do
        if #group.projects > 0 then
            slnx.group(group)
        end
    end
    for prj in premake.solution.eachproject(sln) do
        if prj.group == nil then
            slnx.project(prj)
        end
    end
    _p('</Solution>')
end

--
-- Write a folder entry for a group and write all projects under the group
--

function slnx.group(group)
    local folderName = group.name .. "/"

    local groupParent = group.parent
    while groupParent ~= nil do
        folderName = groupParent.name .. "/" .. folderName
        groupParent = groupParent.parent
    end

    _p('  <Folder Name="/%s">', folderName)
    for _, prj in ipairs(group.projects) do
        slnx.project(prj)
    end
    _p('  </Folder>')
end

--
-- Write out an entry for a project
--

function slnx.project(prj)
    -- Build a relative path from the solution file to the project file
    local projpath = path.translate(
    path.getrelative(prj.solution.location, vstudio.projectfile(prj)), "\\")

    local indent = '  '
    if prj.group ~= nil then
        indent = '    '
    end
    _p('%s<Project Path="%s" Id="%s" />', indent, projpath, prj.uuid)
end

--
-- Write out the contents of the Configurations section, which lists
-- every platform used by at least one project in the slnx.
--

function slnx.configurations(sln)
    local platforms = {}

    for _, cfg in ipairs(sln.vstudio_configs) do
        local platform = cfg.platform

        if platform == "Any CPU" or platform == "Mixed Platforms" then
            if not table.contains(platforms, "Any CPU") then
                table.insert(platforms, "Any CPU")
            end
        else
            if not table.contains(platforms, platform) then
                table.insert(platforms, platform)
            end
        end
    end

    for prj in premake.solution.eachproject(sln) do
        if premake.isdotnetproject(prj) then
            if not table.contains(platforms, "Any CPU") then
                table.insert(platforms, "Any CPU")
            end
        end
    end

    table.sort(platforms)

    _p('  <Configurations>')
    for _, platform in ipairs(platforms) do
        _p('    <Platform Name="%s" />', platform)
    end
    _p('  </Configurations>')
end
