// 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 <libproc.h>
#include <signal.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>
#include <CoreFoundation/CoreFoundation.h>
#include <cstdio>

#include "src/main/cpp/blaze_util.h"
#include "src/main/cpp/blaze_util_platform.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/strings.h"

namespace blaze {

using blaze_util::die;
using blaze_util::pdie;
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);
    string error_desc = DescriptionFromCFError(cf_error_releaser);
    fprintf(stderr, "Warning: couldn't get file system type information for "
            "'%s'", output_base.c_str());
    if (error_desc.length() > 0) {
      fprintf(stderr, " - '%s'", error_desc.c_str());
    }
    fprintf(stderr, "\n");
    return;
  }
  CFScopedReleaser<CFBooleanRef> cf_local_releaser(cf_local);
  if (!CFBooleanGetValue(cf_local_releaser)) {
    fprintf(stderr, "Warning: Output base '%s' is on a non-local drive. This "
            "may lead to surprising failures and undetermined behavior.\n",
            output_base.c_str());
  }
}

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

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

uint64_t ProcessClock() {
  return clock() * (1000000000LL / 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 GetDefaultHostJavabase() {
  const char *java_home = getenv("JAVA_HOME");
  if (java_home) {
    return std::string(java_home);
  }

  FILE *output = popen("/usr/libexec/java_home -v 1.7+", "r");
  if (output == NULL) {
    pdie(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
         "Could not run /usr/libexec/java_home");
  }

  char buf[512];
  char *result = fgets(buf, sizeof(buf), output);
  pclose(output);
  if (result == NULL) {
    die(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
        "No output from /usr/libexec/java_home");
  }

  string javabase = buf;
  if (javabase.empty()) {
    die(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR,
        "Empty output from /usr/libexec/java_home - "
        "install a JDK, or install a JRE and point your JAVA_HOME to it");
  }

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

void WriteSystemSpecificProcessIdentifier(const string& server_dir) {
}

bool VerifyServerProcess(
    int pid, const string& output_base, const string& install_base) {
  // TODO(lberki): This might accidentally kill an unrelated process if the
  // server died and the PID got reused.
  return true;
}

bool KillServerProcess(int pid) {
  killpg(pid, SIGKILL);
  return true;
}

// 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()) {
    fprintf(stderr, "Warning: unable to exclude '%s' from backups\n",
            path.c_str());
    return;
  }
  CFErrorRef cf_error = NULL;
  if (!CFURLSetResourcePropertyForKey(cf_url, kCFURLIsExcludedFromBackupKey,
                                      kCFBooleanTrue, &cf_error)) {
    CFScopedReleaser<CFErrorRef> cf_error_releaser(cf_error);
    string error_desc = DescriptionFromCFError(cf_error_releaser);
    fprintf(stderr, "Warning: unable to exclude '%s' from backups",
            path.c_str());
    if (error_desc.length() > 0) {
      fprintf(stderr, " - '%s'", error_desc.c_str());
    }
    fprintf(stderr, "\n");
    return;
  }
}

}   // namespace blaze.
