// Copyright 2026 Google LLC
//
// 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 main

import (
	"context"
	"flag"
	"fmt"

	"github.com/google/subcommands"
)

type enableCmd struct {
	disk string
}

func (*enableCmd) Name() string {
	return "enable"
}

func (*enableCmd) Synopsis() string {
	return "Enable one or more allowlisted arguments for the next boot"
}

func (*enableCmd) Usage() string {
	return "enable [--disk <disk image>] <arg1> [arg2] ...\n"
}

func (c *enableCmd) SetFlags(f *flag.FlagSet) {
	f.StringVar(&c.disk, "disk", "", "Path to the disk image (empty for live system)")
}

func (c *enableCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{}) subcommands.ExitStatus {
	args := f.Args()
	if len(args) == 0 {
		fmt.Println("Usage: enable [--disk <disk image>] <arg1> [arg2] ...")
		return subcommands.ExitUsageError
	}

	allowlist, _, err := readAllowlist(c.disk)
	if err != nil {
		fmt.Printf("Error reading allowlist: %v\n", err)
		return subcommands.ExitFailure
	}

	bitfield, err := readBitfield(c.disk)
	if err != nil {
		fmt.Printf("Error reading bitfield: %v\n", err)
		return subcommands.ExitFailure
	}

	for _, argToEnable := range args {
		found := false
		for i, arg := range allowlist {
			if argToEnable == arg {
				bitfield |= (1 << i)
				found = true
				break
			}
		}
		if !found {
			fmt.Printf("Error: argument '%s' is not in the allowlist\n", argToEnable)
			return subcommands.ExitFailure
		}
	}

	err = writeBitfield(c.disk, bitfield)
	if err != nil {
		fmt.Printf("Error writing bitfield: %v\n", err)
		return subcommands.ExitFailure
	}

	fmt.Printf("Successfully enabled %v\n", args)
	return subcommands.ExitSuccess
}
