// +build solaris,cgo

package system

import (
	"fmt"
	"unsafe"
)

// #cgo LDFLAGS: -lkstat
// #include <unistd.h>
// #include <stdlib.h>
// #include <stdio.h>
// #include <kstat.h>
// #include <sys/swap.h>
// #include <sys/param.h>
// struct swaptable *allocSwaptable(int num) {
//	struct swaptable *st;
//	struct swapent *swapent;
// 	st = (struct swaptable *)malloc(num * sizeof(swapent_t) + sizeof (int));
//	swapent = st->swt_ent;
//	for (int i = 0; i < num; i++,swapent++) {
//		swapent->ste_path = (char *)malloc(MAXPATHLEN * sizeof (char));
//	}
//	st->swt_n = num;
//	return st;
//}
// void freeSwaptable (struct swaptable *st) {
//	struct swapent *swapent = st->swt_ent;
//	for (int i = 0; i < st->swt_n; i++,swapent++) {
//		free(swapent->ste_path);
//	}
//	free(st);
// }
// swapent_t getSwapEnt(swapent_t *ent, int i) {
//	return ent[i];
// }
// int64_t getPpKernel() {
//	int64_t pp_kernel = 0;
//	kstat_ctl_t *ksc;
//	kstat_t *ks;
//	kstat_named_t *knp;
//	kid_t kid;
//
//	if ((ksc = kstat_open()) == NULL) {
//		return -1;
//	}
//	if ((ks = kstat_lookup(ksc, "unix", 0, "system_pages")) == NULL) {
//		return -1;
//	}
//	if (((kid = kstat_read(ksc, ks, NULL)) == -1) ||
//	    ((knp = kstat_data_lookup(ks, "pp_kernel")) == NULL)) {
//		return -1;
//	}
//	switch (knp->data_type) {
//	case KSTAT_DATA_UINT64:
//		pp_kernel = knp->value.ui64;
//		break;
//	case KSTAT_DATA_UINT32:
//		pp_kernel = knp->value.ui32;
//		break;
//	}
//	pp_kernel *= sysconf(_SC_PAGESIZE);
//	return (pp_kernel > 0 ? pp_kernel : -1);
// }
import "C"

// Get the system memory info using sysconf same as prtconf
func getTotalMem() int64 {
	pagesize := C.sysconf(C._SC_PAGESIZE)
	npages := C.sysconf(C._SC_PHYS_PAGES)
	return int64(pagesize * npages)
}

func getFreeMem() int64 {
	pagesize := C.sysconf(C._SC_PAGESIZE)
	npages := C.sysconf(C._SC_AVPHYS_PAGES)
	return int64(pagesize * npages)
}

// ReadMemInfo retrieves memory statistics of the host system and returns a
//  MemInfo type.
func ReadMemInfo() (*MemInfo, error) {

	ppKernel := C.getPpKernel()
	MemTotal := getTotalMem()
	MemFree := getFreeMem()
	SwapTotal, SwapFree, err := getSysSwap()

	if ppKernel < 0 || MemTotal < 0 || MemFree < 0 || SwapTotal < 0 ||
		SwapFree < 0 {
		return nil, fmt.Errorf("Error getting system memory info %v\n", err)
	}

	meminfo := &MemInfo{}
	// Total memory is total physical memory less than memory locked by kernel
	meminfo.MemTotal = MemTotal - int64(ppKernel)
	meminfo.MemFree = MemFree
	meminfo.SwapTotal = SwapTotal
	meminfo.SwapFree = SwapFree

	return meminfo, nil
}

func getSysSwap() (int64, int64, error) {
	var tSwap int64
	var fSwap int64
	var diskblksPerPage int64
	num, err := C.swapctl(C.SC_GETNSWP, nil)
	if err != nil {
		return -1, -1, err
	}
	st := C.allocSwaptable(num)
	_, err = C.swapctl(C.SC_LIST, unsafe.Pointer(st))
	if err != nil {
		C.freeSwaptable(st)
		return -1, -1, err
	}

	diskblksPerPage = int64(C.sysconf(C._SC_PAGESIZE) >> C.DEV_BSHIFT)
	for i := 0; i < int(num); i++ {
		swapent := C.getSwapEnt(&st.swt_ent[0], C.int(i))
		tSwap += int64(swapent.ste_pages) * diskblksPerPage
		fSwap += int64(swapent.ste_free) * diskblksPerPage
	}
	C.freeSwaptable(st)
	return tSwap, fSwap, nil
}
