//--------------------------------------------------------------------------------------------------
static void GenerateAppLimitsConfig
(
    std::ofstream& cfgStream,
    const legato::App& app
)
//--------------------------------------------------------------------------------------------------
{
    if (app.IsSandboxed() == false)
    {
        cfgStream << "  \"sandboxed\" !f" << std::endl;
    }

    if (app.StartMode() == legato::App::MANUAL)
    {
        cfgStream << "  \"startManual\" !t" << std::endl;
    }

    cfgStream << "  \"maxThreads\" [" << app.MaxThreads().Get() << "]" << std::endl;

    cfgStream << "  \"maxMQueueBytes\" [" << app.MaxMQueueBytes().Get() << "]"
              << std::endl;

    cfgStream << "  \"maxQueuedSignals\" [" << app.MaxQueuedSignals().Get() << "]"
              << std::endl;

    cfgStream << "  \"maxMemoryBytes\" [" << app.MaxMemoryBytes().Get() << "]" << std::endl;

    cfgStream << "  \"cpuShare\" [" << app.CpuShare().Get() << "]" << std::endl;

    if (app.MaxFileSystemBytes().IsSet())
    {
        // This is not supported for unsandboxed apps.
        if (app.IsSandboxed() == false)
        {
            std::cerr << "**** Warning: File system size limit being ignored for unsandboxed"
                      << " application '" << app.Name() << "'." << std::endl;
        }
        else
        {
            cfgStream << "  \"maxFileSystemBytes\" [" << app.MaxFileSystemBytes().Get() << "]"
                      << std::endl;
        }
    }

    if (app.WatchdogTimeout().IsSet())
    {
        cfgStream << "  \"watchdogTimeout\" [" << app.WatchdogTimeout().Get() << "]" << std::endl;
    }

    if (app.WatchdogAction().IsSet())
    {
        cfgStream << "  \"watchdogAction\" \"" << app.WatchdogAction().Get() << "\"" << std::endl;
    }
}
//--------------------------------------------------------------------------------------------------
void CheckForLimitsConflicts
(
    const legato::App& app
)
//--------------------------------------------------------------------------------------------------
{
    size_t maxMemoryBytes = app.MaxMemoryBytes().Get();
    size_t maxFileSystemBytes = app.MaxFileSystemBytes().Get();

    for (const auto& procEnv : app.ProcEnvironments())
    {
        size_t maxLockedMemoryBytes = procEnv.MaxLockedMemoryBytes().Get();

        if (maxLockedMemoryBytes > maxMemoryBytes)
        {
            std::stringstream warning;
            warning << "maxLockedMemoryBytes (" << maxLockedMemoryBytes
                    << ") will be limited by the maxMemoryBytes limit (" << maxMemoryBytes << ").";
            PrintWarning(app, warning.str());
        }

        size_t maxFileBytes = procEnv.MaxFileBytes().Get();
        size_t maxCoreDumpFileBytes = procEnv.MaxCoreDumpFileBytes().Get();

        if (maxCoreDumpFileBytes > maxFileBytes)
        {
            std::stringstream warning;
            warning << "maxCoreDumpFileBytes (" << maxCoreDumpFileBytes
                    << ") will be limited by the maxFileBytes limit (" << maxFileBytes << ").";
            PrintWarning(app, warning.str());
        }

        if (maxCoreDumpFileBytes > maxFileSystemBytes)
        {
            std::stringstream warning;
            warning << "maxCoreDumpFileBytes (" << maxCoreDumpFileBytes
                    << ") will be limited by the maxFileSystemBytes limit ("
                    << maxFileSystemBytes << ") if the core file is inside the sandbox temporary"
                    " file system.";
            PrintWarning(app, warning.str());
        }

        if (maxFileBytes > maxFileSystemBytes)
        {
            std::stringstream warning;
            warning << "maxFileBytes (" << maxFileBytes
                    << ") will be limited by the maxFileSystemBytes limit ("
                    << maxFileSystemBytes << ") if the file is inside the sandbox temporary"
                    " file system.";
            PrintWarning(app, warning.str());
        }
    }
}