package main

import (
	"bytes"
	"context"
	"crypto/ed25519"
	_ "embed"
	"fmt"
	"os"
	"os/signal"

	"github.com/bazelbuild/rules_go/go/runfiles"
	"github.com/spf13/cobra"
	"google.golang.org/protobuf/encoding/prototext"

	"source.monogon.dev/metropolis/proto/api"
	cpb "source.monogon.dev/metropolis/proto/common"

	"source.monogon.dev/metropolis/cli/flagdefs"
	"source.monogon.dev/metropolis/cli/metroctl/core"
	common "source.monogon.dev/metropolis/node"
	"source.monogon.dev/osbase/blkio"
	"source.monogon.dev/osbase/fat32"
)

var installCmd = &cobra.Command{
	Short: "Contains subcommands to install Metropolis via different media.",
	Use:   "install",
}

// bootstrap is a flag controlling node parameters included in the installer
// image. If set, the installed node will bootstrap a new cluster. Otherwise,
// it will try to connect to the cluster which endpoints were provided with
// the --endpoints flag.
var bootstrap = installCmd.PersistentFlags().Bool("bootstrap", false, "Create a bootstrap installer image.")
var bootstrapTPMMode = flagdefs.TPMModePflag(installCmd.PersistentFlags(), "bootstrap-tpm-mode", cpb.ClusterConfiguration_TPM_MODE_REQUIRED, "TPM mode to set on cluster")
var bootstrapStorageSecurityPolicy = flagdefs.StorageSecurityPolicyPflag(installCmd.PersistentFlags(), "bootstrap-storage-security", cpb.ClusterConfiguration_STORAGE_SECURITY_POLICY_NEEDS_ENCRYPTION_AND_AUTHENTICATION, "Storage security policy to set on cluster")
var bundlePath = installCmd.PersistentFlags().StringP("bundle", "b", "", "Path to the Metropolis bundle to be installed")
var nodeParamPath = installCmd.PersistentFlags().String("node-params", "", "Path to the metropolis.proto.api.NodeParameters prototext file (advanced usage only)")

func makeNodeParams() (*api.NodeParameters, error) {
	ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt)

	if err := os.MkdirAll(flags.configPath, 0700); err != nil && !os.IsExist(err) {
		return nil, fmt.Errorf("failed to create config directory: %w", err)
	}

	var params *api.NodeParameters
	if *nodeParamPath != "" {
		nodeParamsRaw, err := os.ReadFile(*nodeParamPath)
		if err != nil {
			return nil, fmt.Errorf("failed to read node-params file: %w", err)
		}
		if err := prototext.Unmarshal(nodeParamsRaw, params); err != nil {
			return nil, fmt.Errorf("failed to parse node-params: %w", err)
		}
	} else {
		params = &api.NodeParameters{}
	}

	if *bootstrap {
		if flags.cluster == "" {
			return nil, fmt.Errorf("when bootstrapping a cluster, the --cluster parameter is required")
		}
		if err := common.ValidateClusterDomain(flags.cluster); err != nil {
			return nil, fmt.Errorf("invalid cluster domain: %w", err)
		}

		// TODO(lorenz): Have a key management story for this
		priv, err := core.GetOrMakeOwnerKey(flags.configPath)
		if err != nil {
			return nil, fmt.Errorf("failed to generate or get owner key: %w", err)
		}
		pub := priv.Public().(ed25519.PublicKey)
		params.Cluster = &api.NodeParameters_ClusterBootstrap_{
			ClusterBootstrap: &api.NodeParameters_ClusterBootstrap{
				OwnerPublicKey: pub,
				InitialClusterConfiguration: &cpb.ClusterConfiguration{
					ClusterDomain:         flags.cluster,
					StorageSecurityPolicy: *bootstrapStorageSecurityPolicy,
					TpmMode:               *bootstrapTPMMode,
				},
			},
		}
	} else {
		cc, err := dialAuthenticated(ctx)
		if err != nil {
			return nil, fmt.Errorf("while dialing node: %w", err)
		}
		mgmt := api.NewManagementClient(cc)
		resT, err := mgmt.GetRegisterTicket(ctx, &api.GetRegisterTicketRequest{})
		if err != nil {
			return nil, fmt.Errorf("while receiving register ticket: %w", err)
		}
		resI, err := mgmt.GetClusterInfo(ctx, &api.GetClusterInfoRequest{})
		if err != nil {
			return nil, fmt.Errorf("while receiving cluster directory: %w", err)
		}

		params.Cluster = &api.NodeParameters_ClusterRegister_{
			ClusterRegister: &api.NodeParameters_ClusterRegister{
				RegisterTicket:   resT.Ticket,
				ClusterDirectory: resI.ClusterDirectory,
				CaCertificate:    resI.CaCertificate,
			},
		}
	}
	return params, nil
}

func external(name, datafilePath string, flag *string) (fat32.SizedReader, error) {
	if flag == nil || *flag == "" {
		rPath, err := runfiles.Rlocation(datafilePath)
		if err != nil {
			return nil, fmt.Errorf("no %s specified", name)
		}
		df, err := os.ReadFile(rPath)
		if err != nil {
			return nil, fmt.Errorf("can't read file: %w", err)
		}
		return bytes.NewReader(df), nil
	}

	f, err := blkio.NewFileReader(*flag)
	if err != nil {
		return nil, fmt.Errorf("failed to open specified %s: %w", name, err)
	}

	return f, nil
}

func init() {
	rootCmd.AddCommand(installCmd)
}
