// Copyright The Monogon Project Authors.
// SPDX-License-Identifier: Apache-2.0

// Implementation included in this file was written with the aim of easing
// integration with the interface exposed at /sys/class/block. It assumes sysfs
// is already mounted at /sys.
package sysfs

import (
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/google/uuid"
)

// PartUUIDMap returns a mapping between partition UUIDs and block device
// names based on information exposed by uevent. UUID keys of the returned
// map are represented as lowercase strings.
func PartUUIDMap() (map[string]string, error) {
	m := make(map[string]string)
	// Get a list of block device symlinks from sysfs.
	const blkDirPath = "/sys/class/block"
	blkDevs, err := os.ReadDir(blkDirPath)
	if err != nil {
		return m, fmt.Errorf("couldn't read %q: %w", blkDirPath, err)
	}
	// Iterate over block device symlinks present in blkDevs, creating a mapping
	// in m for each device with both PARTUUID and DEVNAME keys present in their
	// respective uevent files.
	for _, devInfo := range blkDevs {
		// Read the uevent file and transform it into a string->string map.
		kv, err := ReadUevents(filepath.Join(blkDirPath, devInfo.Name(), "uevent"))
		if err != nil {
			return m, fmt.Errorf("while reading uevents: %w", err)
		}
		// Check that the required keys are present in the map.
		if uuid, name := kv["PARTUUID"], kv["DEVNAME"]; uuid != "" && name != "" {
			m[uuid] = name
		}
	}
	return m, nil
}

var ErrDevNotFound = errors.New("device not found")

// DeviceByPartUUID returns a block device name, given its corresponding
// partition UUID.
func DeviceByPartUUID(id uuid.UUID) (string, error) {
	pm, err := PartUUIDMap()
	if err != nil {
		return "", err
	}
	if bdev, ok := pm[id.String()]; ok {
		return bdev, nil
	}
	return "", ErrDevNotFound
}

// ParentBlockDevice transforms the block device name of a partition, eg
// "sda1", to the name of the block device hosting it, eg "sda".
func ParentBlockDevice(dev string) (string, error) {
	// Build a path pointing to a sysfs block device symlink.
	partLink := filepath.Join("/sys/class/block", dev)
	// Read the symlink at partLink. This should leave us with a path of the form
	// (...)/sda/sdaN.
	linkTgt, err := os.Readlink(partLink)
	if err != nil {
		return "", fmt.Errorf("couldn't read the block device symlink at %q: %w", partLink, err)
	}
	// Remove the last element from the path, leaving us with a path pointing to
	// the block device containting the installer partition, of the form
	// (...)/sda.
	devPath := filepath.Dir(linkTgt)
	// Get the last element of the path, leaving us with just the block device
	// name, eg sda
	devName := filepath.Base(devPath)
	return devName, nil
}

// PartitionBlockDevice returns the name of a block device associated with the
// partition at index in the containing block device dev, eg "nvme0n1pN" for
// "nvme0n1" or "sdaN" for "sda".
func PartitionBlockDevice(dev string, index int) (string, error) {
	dp := filepath.Join("/sys/class/block", dev)
	dir, err := os.ReadDir(dp)
	if err != nil {
		return "", err
	}
	for _, info := range dir {
		// Skip non-directories
		if !info.IsDir() {
			continue
		}
		// Check whether the directory contains a file named 'partition'. If that's
		// the case, read the partition index from it and compare it with the one
		// supplied as a function parameter. If they're equal, return the directory
		// name.
		istr, err := os.ReadFile(filepath.Join(dp, info.Name(), "partition"))
		if os.IsNotExist(err) {
			continue
		}
		if err != nil {
			return "", err
		}
		// istr holds a newline-terminated ASCII-encoded decimal number.
		pi, err := strconv.Atoi(strings.TrimSuffix(string(istr), "\n"))
		if err != nil {
			return "", fmt.Errorf("failed to parse partition index: %w", err)
		}
		if pi == index {
			return info.Name(), nil
		}
	}
	return "", fmt.Errorf("couldn't find partition %d of %q", index, dev)
}
