/*
 * Copyright (C) Tildeslash Ltd. All rights reserved.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * In addition, as a special exception, the copyright holders give
 * permission to link the code of portions of this program with the
 * OpenSSL library under certain conditions as described in each
 * individual source file, and distribute linked combinations
 * including the two.
 *
 * You must obey the GNU Affero General Public License in all respects
 * for all of the code used other than OpenSSL.  
 */


#include "config.h"

#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif

#ifdef HAVE_STRING_H
#include <string.h>
#endif

#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif

#ifdef HAVE_KVM_H
#include <kvm.h>
#endif

#ifdef HAVE_SYS_SYSCTL_H
#include <sys/sysctl.h>
#endif

#ifdef HAVE_SYS_VMMETER_H
#include <sys/vmmeter.h>
#endif

#ifdef HAVE_MACH_MACH_H
#include <mach/mach.h>
#endif

#ifdef HAVE_MACH_HOST_INFO_H
#include <mach/host_info.h>
#endif

#ifdef HAVE_MACH_MACH_HOST_H
#include <mach/mach_host.h>
#endif


#include "monit.h"
#include "process.h"
#include "process_sysdep.h"


/**
 *  System dependent resource gathering code for MacOS X.
 *
 *  @file
 */


#define ARGSSIZE 8192


/* ----------------------------------------------------------------- Private */


static int  hz;
static int  pagesize_kbyte;
static long total_old    = 0;
static long cpu_user_old = 0;
static long cpu_syst_old = 0;


/* ------------------------------------------------------------------ Public */


int init_process_info_sysdep(void) {
  int              mib[2];
  size_t           len;
  struct clockinfo clock;
  uint64_t         memsize;

  mib[0] = CTL_KERN;
  mib[1] = KERN_CLOCKRATE;
  len    = sizeof(clock);
  if (sysctl(mib, 2, &clock, &len, NULL, 0) == -1) {
    DEBUG("system statistic error -- cannot get clock rate: %s\n", STRERROR);
    return FALSE;
  }
  hz     = clock.hz;

  mib[0] = CTL_HW;
  mib[1] = HW_NCPU;
  len    = sizeof(systeminfo.cpus);
  if (sysctl(mib, 2, &systeminfo.cpus, &len, NULL, 0) == -1) {
    DEBUG("system statistic error -- cannot get cpu count: %s\n", STRERROR);
    return FALSE;
  }

  mib[1]  = HW_MEMSIZE;
  len     = sizeof(memsize);
  memsize = 0L;
  if (sysctl(mib, 2, &memsize, &len, NULL, 0 ) == -1) {
    DEBUG("system statistic error -- cannot get real memory amount: %s\n", STRERROR);
    return FALSE;
  }
  systeminfo.mem_kbyte_max = (memsize / 1024);

  mib[1] = HW_PAGESIZE;
  len    = sizeof(pagesize_kbyte);
  if (sysctl(mib, 2, &pagesize_kbyte, &len, NULL, 0) == -1) {
    DEBUG("system statistic error -- cannot get memory page size: %s\n", STRERROR);
    return FALSE;
  }
  pagesize_kbyte /= 1024;

  return TRUE;
}


/**
 * Read all processes to initialize the information tree.
 * @param reference  reference of ProcessTree
 * @return treesize>0 if succeeded otherwise =0.
 */
int initprocesstree_sysdep(ProcessTree_T **reference) {
  int                i;
  size_t             treesize;
  mach_port_t        mytask = mach_task_self();
  ProcessTree_T     *pt;
  struct kinfo_proc *pinfo;
  size_t             pinfo_size = 0;
  char              *args;
  size_t             args_size = 0;
  size_t             size;
  int                mib[4];

  mib[0] = CTL_KERN;
  mib[1] = KERN_PROC;
  mib[2] = KERN_PROC_ALL;
  mib[3] = 0;
  if (sysctl(mib, 4, NULL, &pinfo_size, NULL, 0) < 0) {
    LogError("system statistic error -- sysctl failed: %s\n", STRERROR);
    return FALSE;
  }
  pinfo = CALLOC(1, pinfo_size);
  if (sysctl(mib, 4, pinfo, &pinfo_size, NULL, 0)) {
    FREE(pinfo);
    LogError("system statistic error -- sysctl failed: %s\n", STRERROR);
    return FALSE;
  }
  treesize = pinfo_size / sizeof(struct kinfo_proc);
  pt = CALLOC(sizeof(ProcessTree_T), treesize);

  mib[0] = CTL_KERN;
  mib[1] = KERN_ARGMAX;
  size = sizeof(args_size);
  if (sysctl(mib, 2, &args_size, &size, NULL, 0) == -1) {
    FREE(pinfo);
    FREE(pt);
    LogError("system statistic error -- sysctl failed: %s\n", STRERROR);
    return FALSE;
  }
  args = CALLOC(1, args_size + 1);
  size = args_size; // save for per-process sysctl loop

  for (i = 0; i < treesize; i++) {
    mach_port_t task;

    pt[i].pid       = pinfo[i].kp_proc.p_pid;
    pt[i].ppid      = pinfo[i].kp_eproc.e_ppid;
    pt[i].starttime = pinfo[i].kp_proc.p_starttime.tv_sec;

    args_size = size;
    mib[0] = CTL_KERN;
    mib[1] = KERN_PROCARGS2;
    mib[2] = pt[i].pid;
    if (sysctl(mib, 3, args, &args_size, NULL, 0) != -1) {
      /* KERN_PROCARGS2 sysctl() returns following pseudo structure:
       *        struct {
       *                int argc
       *                char execname[];
       *                char argv[argc][];
       *                char env[][];
       *        }
       * The strings are terminated with '\0' and may have variable '\0' padding
       */
      int  argc = *args;
      char *p = args + sizeof(int); // arguments beginning
      StringBuffer_T cmdline = StringBuffer_create(64);
      p += strlen(p); // skip exename
      while (argc && p < args + args_size) {
        if (*p == 0) { // skip terminating 0 and variable length 0 padding
          p++;
          continue;
        }
        StringBuffer_append(cmdline, argc-- ? "%s " : "%s", p);
        p += strlen(p);
      }
      if (StringBuffer_length(cmdline))
        pt[i].cmdline = Str_dup(StringBuffer_toString(StringBuffer_trim(cmdline)));
      StringBuffer_free(&cmdline);
    }
    if (! pt[i].cmdline || ! *pt[i].cmdline)
      pt[i].cmdline = Str_dup(pinfo[i].kp_proc.p_comm);

    if (pinfo[i].kp_proc.p_stat == SZOMB)
      pt[i].status_flag |= PROCESS_ZOMBIE;
    pt[i].time = get_float_time();

    if (task_for_pid(mytask, pt[i].pid, &task) == KERN_SUCCESS) {
      mach_msg_type_number_t   count;
      task_basic_info_data_t   taskinfo;
      thread_array_t           threadtable;
      unsigned int             threadtable_size;
      thread_basic_info_t      threadinfo;
      thread_basic_info_data_t threadinfo_data;

      count = TASK_BASIC_INFO_COUNT;
      if (task_info(task, TASK_BASIC_INFO, (task_info_t)&taskinfo, &count) == KERN_SUCCESS) {
        pt[i].mem_kbyte   = (unsigned long)(taskinfo.resident_size / 1024);
        pt[i].cputime     = (long)((taskinfo.user_time.seconds + taskinfo.system_time.seconds) * 10 + (taskinfo.user_time.microseconds + taskinfo.system_time.microseconds) / 100000);
        pt[i].cpu_percent = 0;
      }
      if (task_threads(task, &threadtable, &threadtable_size) == KERN_SUCCESS) {
        int j;

        threadinfo = &threadinfo_data;
        for (j = 0; j < threadtable_size; j++) {
          count = THREAD_BASIC_INFO_COUNT;
          if (thread_info(threadtable[j], THREAD_BASIC_INFO, (thread_info_t)threadinfo, &count) == KERN_SUCCESS) {
            if ((threadinfo->flags & TH_FLAGS_IDLE) == 0) {
              pt[i].cputime += (long)((threadinfo->user_time.seconds + threadinfo->system_time.seconds) * 10 + (threadinfo->user_time.microseconds + threadinfo->system_time.microseconds) / 100000);
              pt[i].cpu_percent = 0;
            }
          }
          mach_port_deallocate(mytask, threadtable[j]);
        }
        vm_deallocate(mytask, (vm_address_t)threadtable,threadtable_size * sizeof(thread_act_t));
      }
      mach_port_deallocate(mytask, task); 	
    }
  }
  FREE(args);
  FREE(pinfo);

  *reference = pt;

  return (int)treesize;
}


/**
 * This routine returns 'nelem' double precision floats containing
 * the load averages in 'loadv'; at most 3 values will be returned.
 * @param loadv destination of the load averages
 * @param nelem number of averages
 * @return: 0 if successful, -1 if failed (and all load averages are 0).
 */
int getloadavg_sysdep (double *loadv, int nelem) {
  return getloadavg(loadv, nelem);
}


/**
 * This routine returns kbyte of real memory in use.
 * @return: TRUE if successful, FALSE if failed (or not available)
 */
int used_system_memory_sysdep(SystemInfo_T *si) {
  int                    mib[2];
  unsigned int           pw, pa, pi;
  size_t                 len;
  struct xsw_usage       swap;
  kern_return_t          kret;
  vm_statistics_data_t   page_info;
  mach_msg_type_number_t count;

  /* Memory */
  count = HOST_VM_INFO_COUNT;
  kret  = host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&page_info, &count);
  if (kret != KERN_SUCCESS) {
    DEBUG("system statistic error -- cannot get memory usage\n");
    return FALSE;
  }
  pw = page_info.wire_count * pagesize_kbyte;
  pa = page_info.active_count * pagesize_kbyte;
  pi = page_info.inactive_count * pagesize_kbyte;
  si->total_mem_kbyte = pw + pa + pi;

  /* Swap */
  mib[0] = CTL_VM;
  mib[1] = VM_SWAPUSAGE;
  len    = sizeof(struct xsw_usage);
  if (sysctl(mib, 2, &swap, &len, NULL, 0) == -1) {
    DEBUG("system statistic error -- cannot get swap usage: %s\n", STRERROR);
    si->swap_kbyte_max = 0;
    return FALSE;
  }
  si->swap_kbyte_max   = (unsigned long)(double)(swap.xsu_total) / 1024.;
  si->total_swap_kbyte = (unsigned long)(double)(swap.xsu_used) / 1024.;

  return TRUE;
}


/**
 * This routine returns system/user CPU time in use.
 * @return: TRUE if successful, FALSE if failed
 */
int used_system_cpu_sysdep(SystemInfo_T *si) {
  int                       i;
  long                      total;
  long                      total_new = 0;
  kern_return_t             kret;
  host_cpu_load_info_data_t cpu_info;
  mach_msg_type_number_t    count;

  count = HOST_CPU_LOAD_INFO_COUNT;
  kret  = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&cpu_info, &count);
  if (kret == KERN_SUCCESS) {
    for (i = 0; i < CPU_STATE_MAX; i++)
      total_new += cpu_info.cpu_ticks[i];
    total     = total_new - total_old;
    total_old = total_new;

    si->total_cpu_user_percent = (total > 0)?(int)(1000 * (double)(cpu_info.cpu_ticks[CPU_STATE_USER] - cpu_user_old) / total):-10;
    si->total_cpu_syst_percent = (total > 0)?(int)(1000 * (double)(cpu_info.cpu_ticks[CPU_STATE_SYSTEM] - cpu_syst_old) / total):-10;
    si->total_cpu_wait_percent = 0; /* there is no wait statistic available */

    cpu_user_old = cpu_info.cpu_ticks[CPU_STATE_USER];
    cpu_syst_old = cpu_info.cpu_ticks[CPU_STATE_SYSTEM];

    return TRUE;
  }
  return FALSE;
}

