package http

import (
	"context"
	"net"
	"strconv"

	"github.com/gin-gonic/gin"
	"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
	"github.com/pingcap/log"
	"github.com/tidbcloud/dataflow-service/dataflow-agent-ng/agent/constants"
	"github.com/tidbcloud/dataflow-service/dataflow-agent-ng/idl/pbgen/proto/ng_agent"
	grpchttp "github.com/tidbcloud/dataflow-service/dataflow-agent-ng/pkg/grpc/http"
	httpmiddleware "github.com/tidbcloud/pkgv2/http/middleware"
	"github.com/tidbcloud/pkgv2/logid"
	"github.com/tidbcloud/tiinf/transport/http/tigin"
	"go.uber.org/zap"
	"google.golang.org/grpc"
)

func StartHttpServer(port int, enableTLS bool) error {
	var (
		conn *grpc.ClientConn
		err  error
	)
	ctx := context.Background()
	ctx, cancel := context.WithCancel(ctx)
	defer func() {
		cancel()
		if conn != nil {
			_ = conn.Close()
		}
	}()

	grpcAddr := grpchttp.PortToAddress(constants.GrpcPort)
	mux := grpchttp.MakeGatewayMux(runtime.DefaultHTTPErrorHandler)
	conn, err = grpchttp.GatewayConn(log.L(), grpcAddr, grpchttp.ProdGatewayOptions)
	if err != nil {
		return err
	}
	err = agent.RegisterAgentServiceHandler(ctx, mux, conn)
	if err != nil {
		return err
	}

	gin.SetMode(gin.ReleaseMode)
	eng := tigin.Default()
	eng.Use(
		logid.InjectLogid4GRPCGatewayMW,
		httpmiddleware.TraceRequest,
	)

	eng.Any("/api/v1/*any", gin.WrapH(mux))
	addr := net.JoinHostPort(constants.ListenHost, strconv.Itoa(port))
	log.L().Info("starting agent http(s) server", zap.Bool("enable-tls", enableTLS),
		zap.String("addr", addr))
	if enableTLS {
		return eng.RunTLS(addr, constants.CertFilePath, constants.KeyFilePath)
	}
	return eng.Run(addr)
}
