package hello

import (
	"context"
	"fmt"
	grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
	"log"
	"net"
	"net/http"

	"github.com/tidbcloud/tiinf/sdk/auth"

	"github.com/gin-gonic/gin"

	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
	"google.golang.org/grpc"
	"google.golang.org/grpc/credentials/insecure"
	"google.golang.org/grpc/reflection"
)

func Example_Use_GrpcGatewayGetIdentityInfo() {
	// you need init account client first, the account client is singleton
	auth.InitAccountClientByEndpoint("account-provider-grpc:10000", 0)

	listen, _ := net.Listen("tcp", ":8081")
	server := grpc.NewServer(
		grpc.UnaryInterceptor(
			grpc_middleware.ChainUnaryServer(
				auth.GrpcGatewayGetIdentityInfoUnaryInterceptor(&auth.IdentityAuthOption{
					EnableLog: true,
				}),
				auth.GrpcGatewayPermissionCheckUnaryServerInterceptor(&auth.PermissionCheckerCommonParam{
					IdentityF:                   auth.GrpcGatewayGetIdentityFunc,
					PathPattern2ResourceMap:     pathPattern2ResourceMap,
					PathWhitelist:               pathWhitelist,
					GenAccessParam4GrpcGatewayF: auth.GenAccessParam4GrpcGatewayWithPrefixOrgId,
				}),
			),
		),
	)
	RegisterGreeterServer(server, &helloService{})
	reflection.Register(server)
	go func() {
		// grpc server start at 8081
		err := server.Serve(listen)
		if err != nil {
			fmt.Println("grpc server serve error")
			panic(err)
		}
	}()

	mux := runtime.NewServeMux(
		// add http metadata to grcp context
		runtime.WithMetadata(auth.AddHttpMetadata2GrpcContext),
	)
	options := []grpc.DialOption{
		grpc.WithTransportCredentials(insecure.NewCredentials()),
	}
	err := RegisterGreeterHandlerFromEndpoint(context.Background(), mux, "127.0.0.1:8081", options)
	if err != nil {
		fmt.Println("grpc gateway register handler error")
		panic(err)
	}

	httpServer := http.Server{
		Addr:    ":8082",
		Handler: mux,
	}
	go func() {
		err = httpServer.ListenAndServe()
		if err != nil {
			fmt.Println("http server serve error")
			panic(err)
		}
	}()

	e := gin.Default()
	e.Any("/*any", gin.WrapH(mux))
	e.Run(":8083")
}

type helloService struct {
	UnimplementedGreeterServer
}

func (s *helloService) SayHello(ctx context.Context, req *HelloRequest) (*HelloReply, error) {
	log.Println("### example grpc gateway ###, say hello: ", req.Name)

	reply := HelloReply{
		Message: "done",
	}
	return &reply, nil
}

func (s *helloService) TestName(ctx context.Context, req *HelloRequest) (*HelloReply, error) {
	log.Println("### example grpc gateway ###, test name: ", req.Name)

	reply := HelloReply{
		Message: "done",
	}
	return &reply, nil
}
