package main

import (
	"context"
	"encoding/json"
	"fmt"

	"github.com/spf13/cobra"
	pb "github.com/tidbcloud/config-center/proto/config_center"
	"google.golang.org/grpc"
	"k8s.io/utils/ptr"
)

// defaultVersionCmd represents the cluster_config command
var defaultVersionCmd = &cobra.Command{
	Use:   "default-version",
	Short: "manage default versions",
	Long:  `manage default versions`,
}

func init() {
	rootCmd.AddCommand(defaultVersionCmd)

	defaultVersionCmd.AddCommand(newVersionGetCmd())
	defaultVersionCmd.AddCommand(newVersionUpdateCmd())
	defaultVersionCmd.AddCommand(newVersionDeleteCmd())
	defaultVersionCmd.AddCommand(newVersionListCmd())
}

func newVersionGetCmd() *cobra.Command {
	var clusterType, component, cloudProvider, region, clusterVersion string
	var tenantID uint64
	cmd := &cobra.Command{
		Use:   "get",
		Short: "get default version",
		Long:  `get default version`,
		RunE: func(cmd *cobra.Command, args []string) error {
			var opts []grpc.DialOption
			opts = append(opts, grpc.WithInsecure())
			conn, err := grpc.Dial(configCenterEndpoint, opts...)
			if err != nil {
				panic(err)
			}
			defer conn.Close()
			client := pb.NewConfigCenterServiceClient(conn)

			t, err := client.GetDefaultVersion(context.Background(), &pb.GetDefaultVersionRequest{
				ClusterType:    pb.ClusterType(pb.ClusterType_value[clusterType]),
				CloudProvider:  &cloudProvider,
				Component:      component,
				ClusterVersion: &clusterVersion,
				Region:         &region,
				TenantId:       &tenantID,
			})
			if err == nil {
				txt, _ := json.MarshalIndent(t, "", "    ")
				fmt.Println(string(txt))
			}
			return err
		},
	}

	cmd.Flags().StringVarP(&clusterType, "cluster-type", "T", pb.ClusterType_DEDICATED_TIDB.String(), "cluster type")
	cmd.Flags().StringVar(&component, "component", "tidb", "component name")
	cmd.Flags().StringVar(&cloudProvider, "cloud-provider", "aws", "cloud provider")
	cmd.Flags().StringVar(&region, "region", "", "region")
	cmd.Flags().StringVar(&clusterVersion, "cluster-version", "", "cluster version(used to match dm version)")
	cmd.Flags().Uint64Var(&tenantID, "tenant-id", 0, "tenant-id")

	return cmd
}

func newVersionListCmd() *cobra.Command {
	var clusterType string
	cmd := &cobra.Command{
		Use:   "list",
		Short: "list default version rules",
		Long:  `list default version rules`,
		RunE: func(cmd *cobra.Command, args []string) error {
			var opts []grpc.DialOption
			opts = append(opts, grpc.WithInsecure())
			conn, err := grpc.Dial(configCenterEndpoint, opts...)
			if err != nil {
				panic(err)
			}
			defer conn.Close()
			client := pb.NewConfigCenterServiceClient(conn)

			t, err := client.ListDefaultVersionRules(context.Background(), &pb.ListDefaultVersionRulesRequest{
				ClusterType: pb.ClusterType(pb.ClusterType_value[clusterType]),
				TenantId:    ptr.To(uint64(0)),
			})
			if err == nil {
				txt, _ := json.MarshalIndent(t, "", "    ")
				fmt.Println(string(txt))
			}
			return err
		},
	}

	cmd.Flags().StringVarP(&clusterType, "cluster-type", "T", pb.ClusterType_DEDICATED_TIDB.String(), "cluster type")

	return cmd
}

func newVersionUpdateCmd() *cobra.Command {
	var clusterType, cloudProvider, region, component string
	var tenantID uint64
	cmd := &cobra.Command{
		Use:   "update <Version>",
		Short: "update default version",
		Long:  `update default version`,
		RunE: func(cmd *cobra.Command, args []string) error {
			var opts []grpc.DialOption
			opts = append(opts, grpc.WithInsecure())
			conn, err := grpc.Dial(configCenterEndpoint, opts...)
			if err != nil {
				panic(err)
			}
			defer conn.Close()
			client := pb.NewConfigCenterServiceClient(conn)

			version := args[0]
			t, err := client.UpdateDefaultVersion(context.Background(), &pb.UpdateDefaultVersionRequest{
				ClusterType:   pb.ClusterType(pb.ClusterType_value[clusterType]),
				CloudProvider: &cloudProvider,
				Component:     component,
				Region:        &region,
				TenantId:      &tenantID,
				Version:       version,
			})
			if err == nil {
				txt, _ := json.MarshalIndent(t, "", "    ")
				fmt.Println(string(txt))
			}
			return err
		},
	}
	cmd.Flags().StringVarP(&clusterType, "cluster-type", "T", pb.ClusterType_DEDICATED_TIDB.String(), "cluster type")
	cmd.Flags().StringVar(&cloudProvider, "cloud-provider", "", "cloud provider")
	cmd.Flags().StringVar(&region, "region", "", "region")
	cmd.Flags().StringVar(&component, "component", "", "component name")
	cmd.Flags().Uint64Var(&tenantID, "tenant-id", 0, "tenant-id")

	return cmd
}

func newVersionDeleteCmd() *cobra.Command {
	var clusterType, cloudProvider, region string
	var tenantID uint64
	cmd := &cobra.Command{
		Use:   "delete",
		Short: "delete default version",
		Long:  `delete default version`,
		RunE: func(cmd *cobra.Command, args []string) error {
			var opts []grpc.DialOption
			opts = append(opts, grpc.WithInsecure())
			conn, err := grpc.Dial(configCenterEndpoint, opts...)
			if err != nil {
				panic(err)
			}
			defer conn.Close()
			client := pb.NewConfigCenterServiceClient(conn)

			t, err := client.DeleteDefaultVersion(context.Background(), &pb.DeleteDefaultVersionRequest{
				ClusterType:   pb.ClusterType(pb.ClusterType_value[clusterType]),
				CloudProvider: &cloudProvider,
				Region:        &region,
				TenantId:      &tenantID,
			})
			if err == nil {
				txt, _ := json.MarshalIndent(t, "", "    ")
				fmt.Println(string(txt))
			}
			return err
		},
	}
	cmd.Flags().StringVarP(&clusterType, "cluster-type", "T", pb.ClusterType_DEDICATED_TIDB.String(), "cluster type")
	cmd.Flags().StringVar(&cloudProvider, "cloud-provider", "aws", "cloud provider")
	cmd.Flags().StringVar(&region, "region", "", "region")
	cmd.Flags().Uint64Var(&tenantID, "tenant-id", 0, "tenant-id")

	return cmd
}
