package provider

import (
	"context"

	"sigs.k8s.io/controller-runtime/pkg/client"

	ec2v1beta1 "github.com/crossplane/provider-aws/apis/ec2/v1beta1"

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

type Provider interface {
	Name() string
	Network
	Cluster
	NetworkPeering
	Import
}

type Network interface {
	// NewNetwork returns a new network object.
	NewNetwork(ctx context.Context) *cloudv1.Network
	// ConnectNetwork connects to the network, it return an k8s client used to access the network.
	ConnectNetwork(ctx context.Context, infraCli client.Client, network *cloudv1.Network) (client.Client, error)
	// AfterNetworkCreated is called after the network is created. you can use it to verify tidb-operator、sli-reporter、cert-manager status.
	AfterNetworkCreated(ctx context.Context, infraCli client.Client, tenantCli client.Client, network *cloudv1.Network) error
	// AfterNetworkDeleted is called after the network is deleted. you can use it to verify resources cleanup
	AfterNetworkDeleted(ctx context.Context, infraCli client.Client, tenantCli client.Client, network *cloudv1.Network) error
}

type Cluster interface {
	// NewCluster returns a new cluster object.
	NewCluster(ctx context.Context, network *cloudv1.Network) *cloudv1.Cluster
	// SupportTiFlash returns whether the provider support TiFlash. if return true, will add a TiFlash node for the cluster.
	SupportTiFlash() bool
	// AfterClusterCreated is called after the cluster is created. you can use it to verify cluster monitor is work fine.
	// It only needs to be executed in the cluster e2e test
	AfterClusterCreated(ctx context.Context, infraCli client.Client, tenantCli client.Client, cluster *cloudv1.Cluster) error
	// AfterClusterDeleted is called after the cluster is deleted. you can use it to verify resources cleanup
	// It only needs to be executed in the cluster e2e test
	AfterClusterDeleted(ctx context.Context, infraCli client.Client, tenantCli client.Client, cluster *cloudv1.Cluster) error
}

type NetworkPeering interface {
	// SupportNetworkPeering returns true if the provider supports network peering. if not, the network peering test cases will be ignored.
	SupportNetworkPeering() bool
	// NewPeerVPC create a vpc used for peering.
	// if request vpc and peer vpc are the same AWS account, it will auto accept the peering request.
	NewPeerVPC(ctx context.Context) *ec2v1beta1.VPC
}

type Import interface {
	NewImport(ctx context.Context, cluster *cloudv1.Cluster) *cloudv1.Import
}
