// Copyright 2020 The Monogon Project Authors.
//
// SPDX-License-Identifier: Apache-2.0
//
// 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.

// Package quotactl implements a low-level wrapper around the modern portion of
// Linux's quotactl() syscall. See the fsquota package for a nicer interface to
// the most common part of this API.
package quotactl

import (
	"fmt"
	"os"
	"unsafe"

	"golang.org/x/sys/unix"
)

type QuotaType uint

const (
	QuotaTypeUser QuotaType = iota
	QuotaTypeGroup
	QuotaTypeProject
)

const (
	Q_SYNC uint = ((0x800001 + iota) << 8)
	Q_QUOTAON
	Q_QUOTAOFF
	Q_GETFMT
	Q_GETINFO
	Q_SETINFO
	Q_GETQUOTA
	Q_SETQUOTA
	Q_GETNEXTQUOTA
)

const (
	FlagBLimitsValid = 1 << iota
	FlagSpaceValid
	FlagILimitsValid
	FlagInodesValid
	FlagBTimeValid
	FlagITimeValid
)

type DQInfo struct {
	Bgrace uint64
	Igrace uint64
	Flags  uint32
	Valid  uint32
}

type Quota struct {
	BHardLimit uint64 // Both Byte limits are prescaled by 1024 (so are in KiB), but CurSpace is in B
	BSoftLimit uint64
	CurSpace   uint64
	IHardLimit uint64
	ISoftLimit uint64
	CurInodes  uint64
	BTime      uint64
	ITime      uint64
	Valid      uint32
}

type NextDQBlk struct {
	HardLimitBytes  uint64
	SoftLimitBytes  uint64
	CurrentBytes    uint64
	HardLimitInodes uint64
	SoftLimitInodes uint64
	CurrentInodes   uint64
	BTime           uint64
	ITime           uint64
	Valid           uint32
	ID              uint32
}

type QuotaFormat uint32

// Collected from quota_format_type structs
const (
	// QuotaFormatNone is a special case where all quota information is
	// stored inside filesystem metadata and thus requires no quotaFilePath.
	QuotaFormatNone   QuotaFormat = 0
	QuotaFormatVFSOld QuotaFormat = 1
	QuotaFormatVFSV0  QuotaFormat = 2
	QuotaFormatOCFS2  QuotaFormat = 3
	QuotaFormatVFSV1  QuotaFormat = 4
)

// QuotaOn turns quota accounting and enforcement on
func QuotaOn(fd *os.File, qtype QuotaType, quotaFormat QuotaFormat, quotaFilePath string) error {
	pathArg, err := unix.BytePtrFromString(quotaFilePath)
	if err != nil {
		return err
	}
	_, _, err = unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_QUOTAON|uint(qtype)), uintptr(quotaFormat), uintptr(unsafe.Pointer(pathArg)), 0, 0)
	if err != unix.Errno(0) {
		return err
	}
	return nil
}

// QuotaOff turns quotas off
func QuotaOff(fd *os.File, qtype QuotaType) error {
	_, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_QUOTAOFF|uint(qtype)), 0, 0, 0, 0)
	if err != unix.Errno(0) {
		return err
	}
	return nil
}

// GetFmt gets the quota format used on given filesystem
func GetFmt(fd *os.File, qtype QuotaType) (QuotaFormat, error) {
	var fmt uint32
	_, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_GETFMT|uint(qtype)), 0, uintptr(unsafe.Pointer(&fmt)), 0, 0)
	if err != unix.Errno(0) {
		return 0, err
	}
	return QuotaFormat(fmt), nil
}

// GetInfo gets information about quota files
func GetInfo(fd *os.File, qtype QuotaType) (*DQInfo, error) {
	var info DQInfo
	_, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_GETINFO|uint(qtype)), 0, uintptr(unsafe.Pointer(&info)), 0, 0)
	if err != unix.Errno(0) {
		return nil, err
	}
	return &info, nil
}

// SetInfo sets information about quota files
func SetInfo(fd *os.File, qtype QuotaType, info *DQInfo) error {
	_, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_SETINFO|uint(qtype)), 0, uintptr(unsafe.Pointer(info)), 0, 0)
	if err != unix.Errno(0) {
		return err
	}
	return nil
}

// GetQuota gets user quota structure
func GetQuota(fd *os.File, qtype QuotaType, id uint32) (*Quota, error) {
	var info Quota
	_, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_GETQUOTA|uint(qtype)), uintptr(id), uintptr(unsafe.Pointer(&info)), 0, 0)
	if err != unix.Errno(0) {
		return nil, err
	}
	return &info, nil
}

// GetNextQuota gets disk limits and usage > ID
func GetNextQuota(fd *os.File, qtype QuotaType, id uint32) (*NextDQBlk, error) {
	var info NextDQBlk
	_, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_GETNEXTQUOTA|uint(qtype)), uintptr(id), uintptr(unsafe.Pointer(&info)), 0, 0)
	if err != unix.Errno(0) {
		return nil, err
	}
	return &info, nil
}

// SetQuota sets the given quota
func SetQuota(fd *os.File, qtype QuotaType, id uint32, quota *Quota) error {
	_, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_SETQUOTA|uint(qtype)), uintptr(id), uintptr(unsafe.Pointer(quota)), 0, 0)
	if err != unix.Errno(0) {
		return fmt.Errorf("failed to set quota: %w", err)
	}
	return nil
}

// Sync syncs disk copy of filesystems quotas. If device is empty it syncs all
// filesystems.
func Sync(fd *os.File) error {
	if fd != nil {
		_, _, err := unix.Syscall6(unix.SYS_QUOTACTL_FD, fd.Fd(), uintptr(Q_SYNC), 0, 0, 0, 0)
		if err != unix.Errno(0) {
			return err
		}
	} else {
		_, _, err := unix.Syscall6(unix.SYS_QUOTACTL, uintptr(Q_SYNC), 0, 0, 0, 0, 0)
		if err != unix.Errno(0) {
			return err
		}
	}
	return nil
}
