// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

//go:build zos && s390x

package unix

import (
	"unsafe"
)

// This file simulates fstatfs on z/OS using fstatvfs and w_getmntent.

func Fstatfs(fd int, stat *Statfs_t) (err error) {
	var stat_v Statvfs_t
	err = Fstatvfs(fd, &stat_v)
	if err == nil {
		// populate stat
		stat.Type = 0
		stat.Bsize = stat_v.Bsize
		stat.Blocks = stat_v.Blocks
		stat.Bfree = stat_v.Bfree
		stat.Bavail = stat_v.Bavail
		stat.Files = stat_v.Files
		stat.Ffree = stat_v.Ffree
		stat.Fsid = stat_v.Fsid
		stat.Namelen = stat_v.Namemax
		stat.Frsize = stat_v.Frsize
		stat.Flags = stat_v.Flag
		for passn := 0; passn < 5; passn++ {
			switch passn {
			case 0:
				err = tryGetmntent64(stat)
				break
			case 1:
				err = tryGetmntent128(stat)
				break
			case 2:
				err = tryGetmntent256(stat)
				break
			case 3:
				err = tryGetmntent512(stat)
				break
			case 4:
				err = tryGetmntent1024(stat)
				break
			default:
				break
			}
			//proceed to return if: err is nil (found), err is nonnil but not ERANGE (another error occurred)
			if err == nil || err != nil && err != ERANGE {
				break
			}
		}
	}
	return err
}

func tryGetmntent64(stat *Statfs_t) (err error) {
	var mnt_ent_buffer struct {
		header       W_Mnth
		filesys_info [64]W_Mntent
	}
	var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
	fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
	if err != nil {
		return err
	}
	err = ERANGE //return ERANGE if no match is found in this batch
	for i := 0; i < fs_count; i++ {
		if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
			stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
			err = nil
			break
		}
	}
	return err
}

func tryGetmntent128(stat *Statfs_t) (err error) {
	var mnt_ent_buffer struct {
		header       W_Mnth
		filesys_info [128]W_Mntent
	}
	var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
	fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
	if err != nil {
		return err
	}
	err = ERANGE //return ERANGE if no match is found in this batch
	for i := 0; i < fs_count; i++ {
		if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
			stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
			err = nil
			break
		}
	}
	return err
}

func tryGetmntent256(stat *Statfs_t) (err error) {
	var mnt_ent_buffer struct {
		header       W_Mnth
		filesys_info [256]W_Mntent
	}
	var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
	fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
	if err != nil {
		return err
	}
	err = ERANGE //return ERANGE if no match is found in this batch
	for i := 0; i < fs_count; i++ {
		if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
			stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
			err = nil
			break
		}
	}
	return err
}

func tryGetmntent512(stat *Statfs_t) (err error) {
	var mnt_ent_buffer struct {
		header       W_Mnth
		filesys_info [512]W_Mntent
	}
	var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
	fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
	if err != nil {
		return err
	}
	err = ERANGE //return ERANGE if no match is found in this batch
	for i := 0; i < fs_count; i++ {
		if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
			stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
			err = nil
			break
		}
	}
	return err
}

func tryGetmntent1024(stat *Statfs_t) (err error) {
	var mnt_ent_buffer struct {
		header       W_Mnth
		filesys_info [1024]W_Mntent
	}
	var buffer_size int = int(unsafe.Sizeof(mnt_ent_buffer))
	fs_count, err := W_Getmntent((*byte)(unsafe.Pointer(&mnt_ent_buffer)), buffer_size)
	if err != nil {
		return err
	}
	err = ERANGE //return ERANGE if no match is found in this batch
	for i := 0; i < fs_count; i++ {
		if stat.Fsid == uint64(mnt_ent_buffer.filesys_info[i].Dev) {
			stat.Type = uint32(mnt_ent_buffer.filesys_info[i].Fstname[0])
			err = nil
			break
		}
	}
	return err
}
