// 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 fsquota provides a simplified interface to interact with Linux's
// filesystem qouta API.  It only supports setting quotas on directories, not
// groups or users.  Quotas need to be already enabled on the filesystem to be
// able to use them using this package.  See the quotactl package if you intend
// to use this on a filesystem where quotas need to be enabled manually.
package fsquota

import (
	"fmt"
	"math"
	"os"

	"golang.org/x/sys/unix"

	"source.monogon.dev/metropolis/pkg/fsquota/fsxattrs"
	"source.monogon.dev/metropolis/pkg/fsquota/quotactl"
)

// SetQuota sets the quota of bytes and/or inodes in a given path. To not set a
// limit, set the corresponding argument to zero. Setting both arguments to
// zero removes the quota entirely.  This function can only be called on an
// empty directory. It can't be used to create a quota below a directory which
// already has a quota since Linux doesn't offer hierarchical quotas.
func SetQuota(path string, maxBytes uint64, maxInodes uint64) error {
	dir, err := os.Open(path)
	if err != nil {
		return err
	}
	defer dir.Close()
	source, err := fsinfoGetSource(dir)
	if err != nil {
		return err
	}
	var valid uint32
	if maxBytes > 0 {
		valid |= quotactl.FlagBLimitsValid
	}
	if maxInodes > 0 {
		valid |= quotactl.FlagILimitsValid
	}

	attrs, err := fsxattrs.Get(dir)
	if err != nil {
		return err
	}

	var lastID uint32 = attrs.ProjectID
	if lastID == 0 {
		// No project/quota exists for this directory, assign a new project
		// quota.
		// TODO(lorenz): This is racy, but the kernel does not support
		// atomically assigning quotas. So this needs to be added to the
		// kernels setquota interface. Due to the short time window and
		// infrequent calls this should not be an immediate issue.
		for {
			quota, err := quotactl.GetNextQuota(source, quotactl.QuotaTypeProject, lastID)
			if err == unix.ENOENT || err == unix.ESRCH {
				// We have enumerated all quotas, nothing exists here
				break
			} else if err != nil {
				return fmt.Errorf("failed to call GetNextQuota: %w", err)
			}
			if quota.ID > lastID+1 {
				// Take the first ID in the quota ID gap
				lastID++
				break
			}
			lastID++
		}
	}

	// If both limits are zero, this is a delete operation, process it as such
	if maxBytes == 0 && maxInodes == 0 {
		valid = quotactl.FlagBLimitsValid | quotactl.FlagILimitsValid
		attrs.ProjectID = 0
		attrs.Flags &= ^fsxattrs.FlagProjectInherit
	} else {
		attrs.ProjectID = lastID
		attrs.Flags |= fsxattrs.FlagProjectInherit
	}

	if err := fsxattrs.Set(dir, attrs); err != nil {
		return err
	}

	// Always round up to the nearest block size
	bytesLimitBlocks := uint64(math.Ceil(float64(maxBytes) / float64(1024)))

	return quotactl.SetQuota(source, quotactl.QuotaTypeProject, lastID, &quotactl.Quota{
		BHardLimit: bytesLimitBlocks,
		BSoftLimit: bytesLimitBlocks,
		IHardLimit: maxInodes,
		ISoftLimit: maxInodes,
		Valid:      valid,
	})
}

type Quota struct {
	Bytes      uint64
	BytesUsed  uint64
	Inodes     uint64
	InodesUsed uint64
}

// GetQuota returns the current active quota and its utilization at the given
// path
func GetQuota(path string) (*Quota, error) {
	dir, err := os.Open(path)
	if err != nil {
		return nil, err
	}
	defer dir.Close()
	source, err := fsinfoGetSource(dir)
	if err != nil {
		return nil, err
	}
	attrs, err := fsxattrs.Get(dir)
	if err != nil {
		return nil, err
	}
	if attrs.ProjectID == 0 {
		return nil, os.ErrNotExist
	}
	quota, err := quotactl.GetQuota(source, quotactl.QuotaTypeProject, attrs.ProjectID)
	if err != nil {
		return nil, err
	}
	return &Quota{
		Bytes:      quota.BHardLimit * 1024,
		BytesUsed:  quota.CurSpace,
		Inodes:     quota.IHardLimit,
		InodesUsed: quota.CurInodes,
	}, nil
}
