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

package main

import (
	"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/structfs"
)

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 := newAuthenticatedClient(ctx)
		if err != nil {
			return nil, fmt.Errorf("while creating client: %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) (structfs.Blob, error) {
	if flag == nil || *flag == "" {
		rPath, err := runfiles.Rlocation(datafilePath)
		if err != nil {
			return nil, fmt.Errorf("no %s specified", name)
		}
		return structfs.OSPathBlob(rPath)
	}
	f, err := structfs.OSPathBlob(*flag)
	if err != nil {
		return nil, fmt.Errorf("failed to open specified %s: %w", name, err)
	}

	return f, nil
}

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