// Copyright 2014 The Bazel Authors. All rights reserved.
//
// Licensed 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 "src/main/cpp/blaze_util_platform.h"

#include <sys/types.h>
#include <sys/resource.h>
#include <sys/sysctl.h>
#include <sys/socket.h>
#include <sys/un.h>

#include <libproc.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>

#include <CoreFoundation/CoreFoundation.h>

#include <cerrno>
#include <cstdio>
#include <cstring>

#include "src/main/cpp/blaze_util.h"
#include "src/main/cpp/util/errors.h"
#include "src/main/cpp/util/exit_code.h"
#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/logging.h"
#include "src/main/cpp/util/strings.h"

namespace blaze {

using blaze_util::GetLastErrorString;
using std::string;
using std::vector;

// A stack based class for RAII type handling of CF based types that need
// CFRelease called on them. Checks for NULL before calling release.
template <typename T> class CFScopedReleaser {
 public:
  explicit CFScopedReleaser(T value) : value_(value) { }
  ~CFScopedReleaser() {
    if (isValid()) {
      CFRelease(value_);
    }
  }
  T get() { return value_; }
  operator T() { return value_; }
  bool isValid() { return value_ != NULL; }

 private:
  T value_;

  CFScopedReleaser() { }
  CFScopedReleaser(const CFScopedReleaser&);
  CFScopedReleaser& operator=(CFScopedReleaser&);
};

// Convert a CFStringRef to a UTF8 encoded c string
static string UTF8StringFromCFStringRef(CFStringRef cf_string) {
  std::string utf8_string;
  if (cf_string) {
    CFIndex length = CFStringGetLength(cf_string);
    CFIndex max_size =
        CFStringGetMaximumSizeForEncoding(length, kCFStringEncodingUTF8) + 1;
    vector<char> buffer(max_size);
    if (CFStringGetCString(cf_string, &buffer[0], max_size,
                           kCFStringEncodingUTF8)) {
      utf8_string = &buffer[0];
    }
  }
  return utf8_string;
}

// Extract description from a CFError.
static string DescriptionFromCFError(CFErrorRef cf_err) {
  if (!cf_err) {
    return "";
  }
  CFScopedReleaser<CFStringRef> cf_err_string(CFErrorCopyDescription(cf_err));
  return UTF8StringFromCFStringRef(cf_err_string);
}

string GetOutputRoot() {
  return "/var/tmp";
}

void WarnFilesystemType(const string& output_base) {
  // Check to see if we are on a non-local drive.
  CFScopedReleaser<CFURLRef> cf_url(CFURLCreateFromFileSystemRepresentation(
      kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(output_base.c_str()),
      output_base.length(), true));
  CFBooleanRef cf_local = NULL;
  CFErrorRef cf_error = NULL;
  if (!cf_url.isValid() ||
      !CFURLCopyResourcePropertyForKey(cf_url, kCFURLVolumeIsLocalKey,
                                       &cf_local, &cf_error)) {
    CFScopedReleaser<CFErrorRef> cf_error_releaser(cf_error);
    BAZEL_LOG(WARNING) << "couldn't get file system type information for '"
                       << output_base
                       << "': " << DescriptionFromCFError(cf_error_releaser);
    return;
  }
  CFScopedReleaser<CFBooleanRef> cf_local_releaser(cf_local);
  if (!CFBooleanGetValue(cf_local_releaser)) {
    BAZEL_LOG(WARNING) << "Output base '" << output_base
                       << "' is on a non-local drive. This may lead to "
                          "surprising failures and undetermined behavior.";
  }
}

string GetSelfPath() {
  char pathbuf[PROC_PIDPATHINFO_MAXSIZE] = {};
  int len = proc_pidpath(getpid(), pathbuf, sizeof(pathbuf));
  if (len == 0) {
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
        << "error calling proc_pidpath: " << GetLastErrorString();
  }
  return string(pathbuf, len);
}

uint64_t GetMillisecondsMonotonic() {
  struct timeval ts = {};
  if (gettimeofday(&ts, NULL) < 0) {
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
        << "error calling gettimeofday: " << GetLastErrorString();
  }
  return ts.tv_sec * 1000LL + ts.tv_usec / 1000LL;
}

uint64_t GetMillisecondsSinceProcessStart() {
  return (clock() * 1000LL) / CLOCKS_PER_SEC;
}

void SetScheduling(bool batch_cpu_scheduling, int io_nice_level) {
  // stubbed out so we can compile for Darwin.
}

string GetProcessCWD(int pid) {
  struct proc_vnodepathinfo info = {};
  if (proc_pidinfo(
          pid, PROC_PIDVNODEPATHINFO, 0, &info, sizeof(info)) != sizeof(info)) {
    return "";
  }
  return string(info.pvi_cdir.vip_path);
}

bool IsSharedLibrary(const string &filename) {
  return blaze_util::ends_with(filename, ".dylib");
}

string GetSystemJavabase() {
  string java_home = GetEnv("JAVA_HOME");
  if (!java_home.empty()) {
    return java_home;
  }

  FILE *output = popen("/usr/libexec/java_home -v 1.7+", "r");
  if (output == NULL) {
    return "";
  }

  char buf[512];
  char *result = fgets(buf, sizeof(buf), output);
  pclose(output);
  if (result == NULL) {
    return "";
  }

  string javabase = buf;
  if (javabase.empty()) {
    return "";
  }

  // The output ends with a \n, trim it off.
  return javabase.substr(0, javabase.length()-1);
}

void WriteSystemSpecificProcessIdentifier(
    const string& server_dir, pid_t server_pid) {
}

bool VerifyServerProcess(int pid, const string &output_base) {
  // TODO(lberki): This only checks for the process's existence, not whether
  // its start time matches. Therefore this might accidentally kill an
  // unrelated process if the server died and the PID got reused.
  return killpg(pid, 0) == 0;
}

// Sets a flag on path to exclude the path from Apple's automatic backup service
// (Time Machine)
void ExcludePathFromBackup(const string &path) {
  CFScopedReleaser<CFURLRef> cf_url(CFURLCreateFromFileSystemRepresentation(
      kCFAllocatorDefault, reinterpret_cast<const UInt8 *>(path.c_str()),
      path.length(), true));
  if (!cf_url.isValid()) {
    BAZEL_LOG(WARNING) << "unable to exclude '" << path << "' from backups";
    return;
  }
  CFErrorRef cf_error = NULL;
  if (!CFURLSetResourcePropertyForKey(cf_url, kCFURLIsExcludedFromBackupKey,
                                      kCFBooleanTrue, &cf_error)) {
    CFScopedReleaser<CFErrorRef> cf_error_releaser(cf_error);
    BAZEL_LOG(WARNING) << "unable to exclude '" << path << "' from backups: "
                       << DescriptionFromCFError(cf_error_releaser);
    return;
  }
}

int32_t GetExplicitSystemLimit(const int resource) {
  const char* sysctl_name;
  switch (resource) {
    case RLIMIT_NOFILE:
      sysctl_name = "kern.maxfilesperproc";
      break;
    case RLIMIT_NPROC:
      sysctl_name = "kern.maxprocperuid";
      break;
    default:
      return 0;
  }

  int32_t limit;
  size_t len = sizeof(limit);
  if (sysctlbyname(sysctl_name, &limit, &len, nullptr, 0) == -1) {
    BAZEL_LOG(WARNING) << "failed to get value of sysctl " << sysctl_name
                       << ": " << std::strerror(errno);
    return 0;
  }
  if (len != sizeof(limit)) {
    BAZEL_LOG(WARNING) << "failed to get value of sysctl " << sysctl_name
                       << ": returned data length " << len
                       << " did not match expected size " << sizeof(limit);
    return 0;
  }
  return limit;
}

}   // namespace blaze.
