// 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 <sys/time.h>
#include <sys/types.h>

// Intentionally include `sys/resource.h` after `sys/time.h` and
// `sys/types.h`. This is the suggested include pattern under e.g.,
// BSD, https://www.freebsd.org/cgi/man.cgi?query=setrlimit.
#include <sys/resource.h>

#include <stout/os/strerror.hpp>

#include <stout/unreachable.hpp>

#include "posix/rlimits.hpp"

namespace mesos {
namespace internal {
namespace rlimits {

Try<int> convert(RLimitInfo::RLimit::Type type)
{
  const Error error(
      "Resource type '" + RLimitInfo_RLimit_Type_Name(type) +
      "' not supported");

  switch (type) {
    // Resource types defined in XSI.
    case RLimitInfo::RLimit::RLMT_AS:       return RLIMIT_AS;
    case RLimitInfo::RLimit::RLMT_CORE:     return RLIMIT_CORE;
    case RLimitInfo::RLimit::RLMT_CPU:      return RLIMIT_CPU;
    case RLimitInfo::RLimit::RLMT_DATA:     return RLIMIT_DATA;
    case RLimitInfo::RLimit::RLMT_FSIZE:    return RLIMIT_FSIZE;
    case RLimitInfo::RLimit::RLMT_NOFILE:   return RLIMIT_NOFILE;
    case RLimitInfo::RLimit::RLMT_STACK:    return RLIMIT_STACK;

    // Resource types also defined on BSDs like e.g., OS X.
    case RLimitInfo::RLimit::RLMT_MEMLOCK:  return RLIMIT_MEMLOCK;
    case RLimitInfo::RLimit::RLMT_NPROC:    return RLIMIT_NPROC;
    case RLimitInfo::RLimit::RLMT_RSS:      return RLIMIT_RSS;

    // Resource types defined in >=Linux 2.6.36.
    // NOTE: The resource limits defined for Linux are currently the
    // maximal possible set of understood types. Here we explicitly
    // list all types and in particular do not use a `default` case,
    // see MESOS-3754.
    case RLimitInfo::RLimit::RLMT_LOCKS:
#ifdef RLIMIT_LOCKS
      return RLIMIT_LOCKS;
#else
      return error;
#endif

    case RLimitInfo::RLimit::RLMT_MSGQUEUE:
#ifdef RLIMIT_MSGQUEUE
      return RLIMIT_MSGQUEUE;
#else
      return error;
#endif

    case RLimitInfo::RLimit::RLMT_NICE:
#ifdef RLIMIT_NICE
      return RLIMIT_NICE;
#else
      return error;
#endif

    case RLimitInfo::RLimit::RLMT_RTPRIO:
#ifdef RLIMIT_RTPRIO
      return RLIMIT_RTPRIO;
#else
      return error;
#endif

    case RLimitInfo::RLimit::RLMT_RTTIME:
#ifdef RLIMIT_RTTIME
      return RLIMIT_RTTIME;
#else
      return error;
#endif

    case RLimitInfo::RLimit::RLMT_SIGPENDING:
#ifdef RLIMIT_SIGPENDING
      return RLIMIT_SIGPENDING;
#else
      return error;
#endif

    case RLimitInfo::RLimit::UNKNOWN:
      return Error("Unknown rlimit type");
  }

  UNREACHABLE();
}


Try<Nothing> set(const RLimitInfo::RLimit& limit)
{
  const Try<int> resource = convert(limit.type());
  if (resource.isError()) {
    return Error("Could not convert rlimit: " + resource.error());
  }

  ::rlimit resourceLimit;
  if (limit.has_soft() && limit.has_hard()) {
    resourceLimit.rlim_cur = limit.soft();
    resourceLimit.rlim_max = limit.hard();
  } else if (!limit.has_soft() && !limit.has_hard()) {
    resourceLimit.rlim_cur = RLIM_INFINITY;
    resourceLimit.rlim_max = RLIM_INFINITY;
  } else {
    return Error("Invalid rlimit values");
  }

  if (setrlimit(resource.get(), &resourceLimit) != 0) {
    return Error("Failed to set rlimit: " + os::strerror(errno));
  }

  return Nothing();
}

} // namespace rlimits {
} // namespace internal {
} // namespace mesos {
