// PRE-GENERATED (design session). Switches the DEFAULT output device via IPolicyConfig.
// ⚠️ IPolicyConfig is UNDOCUMENTED COM (widely used, but unofficial). The method order below
// must match the OS vtable — VERIFY on Win10/11 in the dev session before relying on it.
using System;
using System.Runtime.InteropServices;

namespace DansoriEQ.App.Audio;

internal enum ERole { eConsole = 0, eMultimedia = 1, eCommunications = 2 }

[Guid("f8679f50-850a-41cf-9c72-430f290290c8")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IPolicyConfig
{
    // Order matters — placeholders keep SetDefaultEndpoint at the correct vtable slot.
    [PreserveSig] int GetMixFormat(string dev, IntPtr fmt);
    [PreserveSig] int GetDeviceFormat(string dev, bool def, IntPtr fmt);
    [PreserveSig] int ResetDeviceFormat(string dev);
    [PreserveSig] int SetDeviceFormat(string dev, IntPtr endpointFmt, IntPtr mixFmt);
    [PreserveSig] int GetProcessingPeriod(string dev, bool def, IntPtr defPeriod, IntPtr minPeriod);
    [PreserveSig] int SetProcessingPeriod(string dev, IntPtr period);
    [PreserveSig] int GetShareMode(string dev, IntPtr mode);
    [PreserveSig] int SetShareMode(string dev, IntPtr mode);
    [PreserveSig] int GetPropertyValue(string dev, bool store, IntPtr key, IntPtr val);
    [PreserveSig] int SetPropertyValue(string dev, bool store, IntPtr key, IntPtr val);
    [PreserveSig] int SetDefaultEndpoint(string dev, ERole role);
    [PreserveSig] int SetEndpointVisibility(string dev, bool visible);
}

[ComImport, Guid("870af99c-171d-4f9e-af0d-e63df40c2bc9")]
internal class CPolicyConfigClient { }

public static class DefaultDeviceSwitcher
{
    public static void SetDefault(string deviceId)
    {
        var cfg = (IPolicyConfig)new CPolicyConfigClient();
        try
        {
            cfg.SetDefaultEndpoint(deviceId, ERole.eMultimedia);
            cfg.SetDefaultEndpoint(deviceId, ERole.eConsole);
            cfg.SetDefaultEndpoint(deviceId, ERole.eCommunications);
        }
        finally { Marshal.ReleaseComObject(cfg); }
    }
}
