/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "config.h"

#include <stdio.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <inttypes.h>
#include <stdbool.h>

#include <qpid/dispatch/platform.h>
#include <qpid/dispatch/ctools.h>


uintmax_t qd_platform_memory_size(void)
{
    bool found = false;
    uintmax_t rlimit = UINTMAX_MAX;

#if QD_HAVE_GETRLIMIT
    {
        // determine if this process has a hard or soft limit set for its total
        // virtual address space
        struct rlimit rl = {0};
        // note rlim_max >= rlim_cur (see man getrlimit) use smallest value
        if (getrlimit(RLIMIT_AS, &rl) == 0) {
            if (rl.rlim_cur != RLIM_INFINITY) {
                rlimit = (uintmax_t)rl.rlim_cur;
                found = true;
            } else if (rl.rlim_max != RLIM_INFINITY) {
                rlimit = (uintmax_t)rl.rlim_max;
                found = true;
            }
        }
    }
#endif // QD_HAVE_GETRLIMIT

    // although a resource limit may be set be sure it does not exceed the
    // available "fast" memory.

    // @TODO(kgiusti) this is linux-specific (see man proc)
    uintmax_t mlimit = UINTMAX_MAX;
    FILE *minfo_fp = fopen("/proc/meminfo", "r");
    if (minfo_fp) {
        size_t buflen = 0;
        char *buffer = 0;
        uintmax_t tmp;
        while (getline(&buffer, &buflen, minfo_fp) != -1) {
            if (sscanf(buffer, "MemTotal: %"SCNuMAX, &tmp) == 1) {
                mlimit = tmp * 1024;  // MemTotal is in KiB
                found = true;
                break;
            }
        }
        free(buffer);  // allocated by getline
        fclose(minfo_fp);
    }

    // and if qdrouterd is running within a container check the cgroups memory
    // controller. Hard and soft memory limits can be set.

    uintmax_t climit = UINTMAX_MAX;
    {
        uintmax_t soft = UINTMAX_MAX;
        uintmax_t hard = UINTMAX_MAX;
        bool c_set = false;

        FILE *cg_fp = fopen("/sys/fs/cgroup/memory/memory.limit_in_bytes", "r");
        if (cg_fp) {
            if (fscanf(cg_fp, "%"SCNuMAX, &hard) == 1) {
                c_set = true;
            }
            fclose(cg_fp);
        }

        cg_fp = fopen("/sys/fs/cgroup/memory/memory.soft_limit_in_bytes", "r");
        if (cg_fp) {
            if (fscanf(cg_fp, "%"SCNuMAX, &soft) == 1) {
                c_set = true;
            }
            fclose(cg_fp);
        }

        if (c_set) {
            climit = MIN(soft, hard);
            found = true;
        }
    }

    if (found) {
        uintmax_t tmp = MIN(mlimit, climit);
        return MIN(rlimit, tmp);
    }

    return 0;
}
