/* Copyright libuv project contributors. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
 * IN THE SOFTWARE.
 */

#include "uv.h"
#include "internal.h"

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>

#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <utmp.h>
#include <libgen.h>

#include <sys/protosw.h>
#include <procinfo.h>
#include <sys/proc.h>
#include <sys/procfs.h>

#include <ctype.h>

#include <sys/mntctl.h>
#include <sys/vmount.h>
#include <limits.h>
#include <strings.h>
#include <sys/vnode.h>

#include <as400_protos.h>


typedef struct {
  int bytes_available;
  int bytes_returned;
  char current_date_and_time[8];
  char system_name[8];
  char elapsed_time[6];
  char restricted_state_flag;
  char reserved;
  int percent_processing_unit_used;
  int jobs_in_system;
  int percent_permanent_addresses;
  int percent_temporary_addresses;
  int system_asp;
  int percent_system_asp_used;
  int total_auxiliary_storage;
  int current_unprotected_storage_used;
  int maximum_unprotected_storage_used;
  int percent_db_capability;
  int main_storage_size;
  int number_of_partitions;
  int partition_identifier;
  int reserved1;
  int current_processing_capacity;
  char processor_sharing_attribute;
  char reserved2[3];
  int number_of_processors;
  int active_jobs_in_system;
  int active_threads_in_system;
  int maximum_jobs_in_system;
  int percent_temporary_256mb_segments_used;
  int percent_temporary_4gb_segments_used;
  int percent_permanent_256mb_segments_used;
  int percent_permanent_4gb_segments_used;
  int percent_current_interactive_performance;
  int percent_uncapped_cpu_capacity_used;
  int percent_shared_processor_pool_used;
  long main_storage_size_long;
} SSTS0200;


static int get_ibmi_system_status(SSTS0200* rcvr) {
  /* rcvrlen is input parameter 2 to QWCRSSTS */
  unsigned int rcvrlen = sizeof(*rcvr);

  /* format is input parameter 3 to QWCRSSTS ("SSTS0200" in EBCDIC) */
  unsigned char format[] = {0xE2, 0xE2, 0xE3, 0xE2, 0xF0, 0xF2, 0xF0, 0xF0};

  /* reset_status is input parameter 4 to QWCRSSTS ("*NO       " in EBCDIC) */
  unsigned char reset_status[] = {
    0x5C, 0xD5, 0xD6, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40
  };

  /* errcode is input parameter 5 to QWCRSSTS */
  struct _errcode {
    int bytes_provided;
    int bytes_available;
    char msgid[7];
  } errcode;

  /* qwcrssts_pointer is the 16-byte tagged system pointer to QWCRSSTS */
  ILEpointer __attribute__((aligned(16))) qwcrssts_pointer;

  /* qwcrssts_argv is the array of argument pointers to QWCRSSTS */
  void* qwcrssts_argv[6];

  /* Set the IBM i pointer to the QSYS/QWCRSSTS *PGM object */
  int rc = _RSLOBJ2(&qwcrssts_pointer, RSLOBJ_TS_PGM, "QWCRSSTS", "QSYS");

  if (rc != 0)
    return rc;

  /* initialize the QWCRSSTS returned info structure */
  memset(rcvr, 0, sizeof(*rcvr));

  /* initialize the QWCRSSTS error code structure */
  memset(&errcode, 0, sizeof(errcode));
  errcode.bytes_provided = sizeof(errcode);

  /* initialize the array of argument pointers for the QWCRSSTS API */
  qwcrssts_argv[0] = rcvr;
  qwcrssts_argv[1] = &rcvrlen;
  qwcrssts_argv[2] = &format;
  qwcrssts_argv[3] = &reset_status;
  qwcrssts_argv[4] = &errcode;
  qwcrssts_argv[5] = NULL;

  /* Call the IBM i QWCRSSTS API from PASE */
  rc = _PGMCALL(&qwcrssts_pointer, (void**)&qwcrssts_argv, 0);

  return rc;
}


uint64_t uv_get_free_memory(void) {
  SSTS0200 rcvr;

  if (get_ibmi_system_status(&rcvr))
    return 0;

  /* The amount of main storage, in kilobytes, in the system. */
  uint64_t main_storage_size = rcvr.main_storage_size;

  /* The current amount of storage in use for temporary objects.
   * in millions (M) of bytes.
   */
  uint64_t current_unprotected_storage_used =
    rcvr.current_unprotected_storage_used * 1024ULL;

  uint64_t free_storage_size =
    (main_storage_size - current_unprotected_storage_used) * 1024ULL;

  return free_storage_size < 0 ? 0 : free_storage_size;
}


uint64_t uv_get_total_memory(void) {
  SSTS0200 rcvr;

  if (get_ibmi_system_status(&rcvr))
    return 0;

  return (uint64_t)rcvr.main_storage_size * 1024ULL;
}


uint64_t uv_get_constrained_memory(void) {
  return 0;  /* Memory constraints are unknown. */
}


void uv_loadavg(double avg[3]) {
  SSTS0200 rcvr;

  if (get_ibmi_system_status(&rcvr)) {
    avg[0] = avg[1] = avg[2] = 0;
    return;
  }

  /* The average (in tenths) of the elapsed time during which the processing
   * units were in use. For example, a value of 411 in binary would be 41.1%.
   * This percentage could be greater than 100% for an uncapped partition.
   */
  double processing_unit_used_percent =
    rcvr.percent_processing_unit_used / 1000.0;

  avg[0] = avg[1] = avg[2] = processing_unit_used_percent;
}


int uv_resident_set_memory(size_t* rss) {
  *rss = 0;
  return 0;
}


int uv_uptime(double* uptime) {
  return UV_ENOSYS;
}


int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
  unsigned int numcpus, idx = 0;
  uv_cpu_info_t* cpu_info;

  *cpu_infos = NULL;
  *count = 0;

  numcpus = sysconf(_SC_NPROCESSORS_ONLN);

  *cpu_infos = uv__malloc(numcpus * sizeof(uv_cpu_info_t));
  if (!*cpu_infos) {
    return UV_ENOMEM;
  }

  cpu_info = *cpu_infos;
  for (idx = 0; idx < numcpus; idx++) {
    cpu_info->speed = 0;
    cpu_info->model = uv__strdup("unknown");
    cpu_info->cpu_times.user = 0;
    cpu_info->cpu_times.sys = 0;
    cpu_info->cpu_times.idle = 0;
    cpu_info->cpu_times.irq = 0;
    cpu_info->cpu_times.nice = 0;
    cpu_info++;
  }
  *count = numcpus;

  return 0;
}

