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

package main

import (
	"context"
	"errors"
	"fmt"
	"log"
	"os"
	"os/exec"
	"os/signal"

	"github.com/spf13/cobra"
	"google.golang.org/grpc"

	"source.monogon.dev/metropolis/cli/metroctl/core"
	"source.monogon.dev/metropolis/node/core/rpc"
	"source.monogon.dev/metropolis/node/core/rpc/resolver"
	apb "source.monogon.dev/metropolis/proto/api"
)

var takeownershipCommand = &cobra.Command{
	Use:   "takeownership",
	Short: "Takes ownership of a new Metropolis cluster",
	Long: `This takes ownership of a new Metropolis cluster by asking the new
cluster to issue an owner certificate to for the owner key generated by a
previous invocation of metroctl install on this machine. A single cluster
endpoint must be provided with the --endpoints parameter.`,
	Args: PrintUsageOnWrongArgs(cobra.ExactArgs(0)),
	RunE: func(cmd *cobra.Command, _ []string) error {
		ctx, _ := signal.NotifyContext(context.Background(), os.Interrupt)
		if len(flags.clusterEndpoints) != 1 {
			return fmt.Errorf("takeownership requires a single cluster endpoint to be provided with the --endpoints parameter")
		}

		contextName, err := cmd.Flags().GetString("context")
		if err != nil || contextName == "" {
			return fmt.Errorf("takeownership requires a valid context name to be provided with the --context parameter")
		}

		ca, err := core.GetClusterCAWithTOFU(ctx, connectOptions())
		if err != nil {
			return fmt.Errorf("could not retrieve cluster CA: %w", err)
		}

		// Retrieve the cluster owner's private key, and use it to construct
		// ephemeral credentials. Then, dial the cluster.
		opk, err := core.GetOwnerKey(flags.configPath)
		if errors.Is(err, core.ErrNoCredentials) {
			return fmt.Errorf("owner key does not exist. takeownership needs to be executed on the same system that has previously installed the cluster using metroctl install")
		}
		if err != nil {
			return fmt.Errorf("couldn't get owner's key: %w", err)
		}
		opts, err := core.DialOpts(ctx, connectOptions())
		if err != nil {
			return fmt.Errorf("while configuring cluster dial opts: %w", err)
		}
		creds, err := rpc.NewEphemeralCredentials(opk, rpc.WantRemoteCluster(ca))
		if err != nil {
			return fmt.Errorf("while generating ephemeral credentials: %w", err)
		}
		opts = append(opts, grpc.WithTransportCredentials(creds))

		cc, err := grpc.Dial(resolver.MetropolisControlAddress, opts...)
		if err != nil {
			return fmt.Errorf("while dialing the cluster: %w", err)
		}
		aaa := apb.NewAAAClient(cc)

		ownerCert, err := rpc.RetrieveOwnerCertificate(ctx, aaa, opk)
		if err != nil {
			return fmt.Errorf("failed to retrive owner certificate from cluster: %w", err)
		}

		if err := core.WriteOwnerCertificate(flags.configPath, ownerCert.Certificate[0]); err != nil {
			log.Printf("Failed to store retrieved owner certificate: %v", err)
			return fmt.Errorf("sorry, the cluster has been lost as taking ownership cannot be repeated. Fix the reason the file couldn't be written and reinstall the node")
		}
		log.Print("Successfully retrieved owner credentials! You now own this cluster. Setting up kubeconfig now...")

		// If the user has metroctl in their path, use the metroctl from path as
		// a credential plugin. Otherwise use the path to the currently-running
		// metroctl.
		metroctlPath := "metroctl"
		if _, err := exec.LookPath("metroctl"); err != nil {
			metroctlPath, err = os.Executable()
			if err != nil {
				return fmt.Errorf("failed to create kubectl entry as metroctl is neither in PATH nor can its absolute path be determined: %w", err)
			}
		}
		// TODO(q3k, issues/144): this only works as long as all nodes are kubernetes controller
		// nodes. This won't be the case for too long. Figure this out.
		configName := "metroctl"
		if err := core.InstallKubeletConfig(ctx, metroctlPath, connectOptions(), configName, flags.clusterEndpoints[0]); err != nil {
			return fmt.Errorf("failed to install metroctl/k8s integration: %w", err)
		}
		log.Printf("Success! kubeconfig is set up. You can now run kubectl --context=%s ... to access the Kubernetes cluster.", configName)
		return nil
	},
}

func init() {
	takeownershipCommand.Flags().String("context", "metroctl", "The name for the kubernetes context to configure")
	clusterCmd.AddCommand(takeownershipCommand)
}
