package message_test

import (
	"testing"

	"google.golang.org/protobuf/encoding/protojson"

	"github.com/stretchr/testify/require"
	regionalapipb "github.com/tidbcloud/infra-provider/api/tidbcloud/regional-server/v1"
	"github.com/tidbcloud/infra-provider/regional-server/pkg/common/message"
	"google.golang.org/protobuf/proto"
)

func TestGetVpcPeeringReqValidatable(t *testing.T) {
	v := message.GetVpcPeeringReqValidatable{
		&regionalapipb.GetVpcPeeringRequest{},
	}
	require.Error(t, v.Validate())
	v.GetVpcPeeringRequest.VpcPeeringId = "foo"
	require.NoError(t, v.Validate())
}

func TestLisVpcPeeringReqValidatebale(t *testing.T) {
	v := message.ListVpcPeeringReqValidatable{
		&regionalapipb.ListVpcPeeringsRequest{},
	}
	require.Error(t, v.Validate())
	v.ListVpcPeeringsRequest.TenantId = "foo"
	require.NoError(t, v.Validate())
	v.ListVpcPeeringsRequest.ProjectId = "foo"
	require.NoError(t, v.Validate())
	v.ListVpcPeeringsRequest.ShowStatusOnly = true
	require.NoError(t, v.Validate())
}

func TestDeleteVpcPeeringReqValidatable(t *testing.T) {
	v := message.DeleteVpcPeeringReqValidatable{
		&regionalapipb.DeleteVpcPeeringRequest{},
	}
	require.Error(t, v.Validate())
	v.DeleteVpcPeeringRequest.VpcPeeringId = "foo"
	require.NoError(t, v.Validate())
}

func cp(in proto.Message, out proto.Message) error {
	bs, err := protojson.Marshal(in)
	if err != nil {
		return err
	}
	if err := protojson.Unmarshal(bs, out); err != nil {
		return err
	}
	return nil
}

func TestCreateVpcPeeringReqValidatable(t *testing.T) {
	vpcpeering := &regionalapipb.VpcPeering{
		Id:                   "foo",
		TenantId:             "foo",
		ProjectId:            "foo",
		DestinationCidrBlock: "10.0.0.0/16",
		Info: &regionalapipb.VpcPeering_Aws_{
			Aws: &regionalapipb.VpcPeering_Aws{
				SourceVpcId:          "vpc-foo",
				SourceAccountId:      "foo",
				DestinationVpcId:     "vpc-bar",
				DestinationAccountId: "bar",
				DestinationRegion:    "us-west-2",
			},
		},
	}
	v := &message.CreateVpcPeeringReqValidatable{
		&regionalapipb.CreateVpcPeeringRequest{
			VpcPeering: vpcpeering,
		},
	}
	require.NoError(t, v.Validate())
	{
		req := new(regionalapipb.CreateVpcPeeringRequest)
		require.NoError(t, cp(v.CreateVpcPeeringRequest, req))
		req.VpcPeering.Id = ""
		require.Error(t, (&message.CreateVpcPeeringReqValidatable{req}).Validate())
	}
	{
		req := new(regionalapipb.CreateVpcPeeringRequest)
		require.NoError(t, cp(v.CreateVpcPeeringRequest, req))
		req.VpcPeering.TenantId = ""
		require.Error(t, (&message.CreateVpcPeeringReqValidatable{req}).Validate())
	}
	{
		req := new(regionalapipb.CreateVpcPeeringRequest)
		require.NoError(t, cp(v.CreateVpcPeeringRequest, req))
		req.VpcPeering.ProjectId = ""
		require.Error(t, (&message.CreateVpcPeeringReqValidatable{req}).Validate())
	}
	{
		req := new(regionalapipb.CreateVpcPeeringRequest)
		require.NoError(t, cp(v.CreateVpcPeeringRequest, req))
		req.VpcPeering.DestinationCidrBlock = ""
		require.Error(t, (&message.CreateVpcPeeringReqValidatable{req}).Validate())
	}
}

func TestAWSInfoValidatable(t *testing.T) {
	v := &regionalapipb.VpcPeering_Aws{
		SourceVpcId:          "vpc-foo",
		SourceAccountId:      "foo",
		DestinationVpcId:     "vpc-bar",
		DestinationAccountId: "bar",
		DestinationRegion:    "us-west-2",
	}
	require.NoError(t, (&message.AWSInfoValidatable{v}).Validate())
	{
		iv := new(regionalapipb.VpcPeering_Aws)
		require.NoError(t, cp(v, iv))
		iv.SourceVpcId = ""
		require.Error(t, (&message.AWSInfoValidatable{iv}).Validate())
	}
	{
		iv := new(regionalapipb.VpcPeering_Aws)
		require.NoError(t, cp(v, iv))
		iv.SourceAccountId = ""
		require.Error(t, (&message.AWSInfoValidatable{iv}).Validate())
	}
	{
		iv := new(regionalapipb.VpcPeering_Aws)
		require.NoError(t, cp(v, iv))
		iv.DestinationAccountId = ""
		require.Error(t, (&message.AWSInfoValidatable{iv}).Validate())
	}
	{
		iv := new(regionalapipb.VpcPeering_Aws)
		require.NoError(t, cp(v, iv))
		iv.DestinationVpcId = ""
		require.Error(t, (&message.AWSInfoValidatable{iv}).Validate())
	}
}

func TestGCPInfoValidatable(t *testing.T) {
	v := &regionalapipb.VpcPeering_Gcp{
		SourceProjectId:        "foo",
		SourceNetworkName:      "vpc-foo",
		DestinationProjectId:   "bar",
		DestinationNetworkName: "vpc-bar",
	}
	require.NoError(t, (&message.GCPInfoValidatable{v}).Validate())
	{
		iv := new(regionalapipb.VpcPeering_Gcp)
		require.NoError(t, cp(v, iv))
		iv.SourceProjectId = ""
		require.Error(t, (&message.GCPInfoValidatable{iv}).Validate())
	}
	{
		iv := new(regionalapipb.VpcPeering_Gcp)
		require.NoError(t, cp(v, iv))
		iv.SourceNetworkName = ""
		require.Error(t, (&message.GCPInfoValidatable{iv}).Validate())
	}
	{
		iv := new(regionalapipb.VpcPeering_Gcp)
		require.NoError(t, cp(v, iv))
		iv.DestinationProjectId = ""
		require.Error(t, (&message.GCPInfoValidatable{iv}).Validate())
	}
	{
		iv := new(regionalapipb.VpcPeering_Gcp)
		require.NoError(t, cp(v, iv))
		iv.DestinationNetworkName = ""
		require.Error(t, (&message.GCPInfoValidatable{iv}).Validate())
	}
}
