package main

// Usage:
// It's a tools to modify the CR in Infra API when we do rush repairs online.
// In this snippets, I have added an example to read the CR in Infra API and Gardener API Server

import (
	"context"
	"fmt"
	"log"
	"path/filepath"

	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/types"
	"k8s.io/client-go/tools/clientcmd"
	"k8s.io/client-go/util/homedir"
	"sigs.k8s.io/controller-runtime/pkg/client"

	shootapi "github.com/tidbcloud/infra-api/pkg/gardener/core/apis/v1beta1"

	cloudv1 "github.com/tidbcloud/infra-api/api/v1"
)

func getInfraAPIClient() client.Client {
	scheme := runtime.NewScheme()
	_ = cloudv1.AddToScheme(scheme)
	var kubeconfig string

	home := homedir.HomeDir()
	kubeconfig = filepath.Join(home, ".kube", "infra-staging")
	config, _ := clientcmd.BuildConfigFromFlags("", kubeconfig)
	cli, err := client.New(config, client.Options{Scheme: scheme})
	if err != nil {
		log.Fatal(err)
	}
	return cli
}

func getGardenerClient() client.Client {
	scheme := runtime.NewScheme()
	_ = shootapi.AddToScheme(scheme)
	var kubeconfig string

	home := homedir.HomeDir()
	kubeconfig = filepath.Join(home, ".kube", "garden-staging")
	config, _ := clientcmd.BuildConfigFromFlags("", kubeconfig)
	cli, err := client.New(config, client.Options{Scheme: scheme})
	if err != nil {
		log.Fatal(err)
	}
	return cli
}

func getNetworkCIDRAndVPCCidrBlock(providerType string, shoot shootapi.Shoot, networkStatusFromProvider *cloudv1.GardenerNetworkStatus) error {
	cidr := shoot.Spec.Networking.Nodes
	networkStatusFromProvider.VPCCidrBlock = *cidr
	return nil
}

func main() {
	cli := getInfraAPIClient()
	gardenCli := getGardenerClient()

	networks := cloudv1.NetworkList{}
	ctx := context.Background()
	_ = cli.List(ctx, &networks)

	shoots := shootapi.ShootList{}
	_ = gardenCli.List(ctx, &shoots)

	for _, network := range networks.Items {
		gardenerStatus, _ := cloudv1.GardenerNetworkStatusFromNetwork(&network)
		current := network.Spec.CIDR

		for _, shoot := range shoots.Items {
			if gardenerStatus.ShootName == shoot.Name {
				providerType := shoot.Spec.Provider.Type
				testnetworkStatusFromProvider := &cloudv1.GardenerNetworkStatus{}
				_ = getNetworkCIDRAndVPCCidrBlock(providerType, shoot, testnetworkStatusFromProvider)
				if current != testnetworkStatusFromProvider.VPCCidrBlock {
					fmt.Printf("different node cidrs found for network %s, real %s, current %s\n", types.NamespacedName{Namespace: network.Namespace, Name: network.Name}, testnetworkStatusFromProvider.VPCCidrBlock, current)
				}
			}
		}
	}

}
