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

package efivarfs

import (
	"encoding/binary"
	"errors"
	"fmt"
	"os"
	"sync"
)

// OSIndications is a bitset used to indicate firmware support for various
// features as well as to trigger some of these features.
// If a constant ends in Supported, it cannot be triggered, the others
// can be.
type OSIndications uint64

const (
	// Indicates that on next boot firmware should boot to a firmware-provided
	// UI instead of the normal boot order.
	BootToFirmwareUI = OSIndications(1 << iota)
	// Indicates that firmware supports timestamp-based revocation and the
	// "dbt" authorized timestamp database variable.
	TimestampRevocationSupported
	// Indicates that on next boot firmware should look for an EFI update
	// capsule on an EFI system partition and try to install it.
	FileCapsuleDelivery
	// Indicates that firmware supports UEFI FMP update capsules.
	FirmwareManagementProtocolCapsuleSupported
	// Indicates that firmware supports reporting results of deferred (i.e.
	// processed on next boot) capsule installs via variables.
	CapsuleResultVarSupported
	// Indicates that firmware should skip Boot# processing on next boot
	// and instead use OsRecovery# for selecting a load option.
	StartOSRecovery
	// Indicates that firmware should skip Boot# processing on next boot
	// and instead use PlatformRecovery# for selecting a load option.
	StartPlatformRecovery
	// Indicates that firmware should collect the current config and report
	// the data to the EFI system configuration table on next boot.
	JSONConfigDataRefresh
)

// osIndicationMutex protects against race conditions in read-modify-write
// sequences on the OsIndications EFI variable.
var osIndicationsMutex sync.Mutex

// OSIndicationsSupported indicates which of the OS indication features and
// actions that the firmware supports.
func OSIndicationsSupported() (OSIndications, error) {
	osIndicationsRaw, _, err := Read(ScopeGlobal, "OsIndicationsSupported")
	if err != nil {
		return 0, fmt.Errorf("unable to read OsIndicationsSupported: %w", err)
	}
	if len(osIndicationsRaw) != 8 {
		return 0, fmt.Errorf("value of OsIndicationsSupported is not 8 bytes / 64 bits, is %d bytes", len(osIndicationsRaw))
	}
	return OSIndications(binary.LittleEndian.Uint64(osIndicationsRaw)), nil
}

// SetOSIndications sets all OS indication bits set in i in firmware. It does
// not clear any already-set bits, use ClearOSIndications for that.
func SetOSIndications(i OSIndications) error {
	return modifyOSIndications(func(prev OSIndications) OSIndications {
		return prev | i
	})
}

// ClearOSIndications clears all OS indication bits set in i in firmware.
// Note that this effectively inverts i, bits set in i will be cleared.
func ClearOSIndications(i OSIndications) error {
	return modifyOSIndications(func(prev OSIndications) OSIndications {
		return prev & ^i
	})
}

func modifyOSIndications(f func(prev OSIndications) OSIndications) error {
	osIndicationsMutex.Lock()
	defer osIndicationsMutex.Unlock()

	var osIndications OSIndications
	rawIn, _, err := Read(ScopeGlobal, "OsIndications")
	if err == nil && len(rawIn) == 8 {
		osIndications = OSIndications(binary.LittleEndian.Uint64(rawIn))
	} else if err != nil && !errors.Is(err, os.ErrNotExist) {
		return fmt.Errorf("unable to read OsIndications variable: %w", err)
	}
	osIndications = f(osIndications)
	var raw [8]byte
	binary.LittleEndian.PutUint64(raw[:], uint64(osIndications))
	if err := Write(ScopeGlobal, "OsIndications", AttrNonVolatile|AttrRuntimeAccess, raw[:]); err != nil {
		return fmt.Errorf("failed to write OSIndications variable: %w", err)
	}
	return nil
}
