package httpsr

import (
	"context"
	"fmt"
	"git.makemake.in/kzkzzzz/mycommon/graceful"
	"github.com/gin-contrib/pprof"
	"github.com/gin-gonic/gin"
	"log"
	"net"
	"net/http"
	"time"
)

var _ graceful.IRunner = (*PProf)(nil)

type PProf struct {
	conf *pprofConf
	hs   *http.Server
}
type pprofConf struct {
	Port int
}

type PProfOpt func(*pprofConf)

func NewPProf(opts ...PProfOpt) *PProf {
	engine := gin.Default()
	pprof.Register(engine)

	p := &PProf{
		conf: &pprofConf{},
		hs: &http.Server{
			Handler: engine,
		},
	}
	for _, opt := range opts {
		opt(p.conf)
	}

	return p
}

func (p *PProf) Run(ctx context.Context) error {
	// 端口如果=0, 监听随机端口
	addr0 := fmt.Sprintf(":%d", p.conf.Port)
	lis, err := net.Listen("tcp", addr0)
	if err != nil {
		return err
	}

	// 获取监听的端口
	port := lis.Addr().(*net.TCPAddr).Port

	addr := fmt.Sprintf(":%d", port)
	log.Printf("http pprof server listen on %s", addr)

	p.hs.Addr = addr

	err = p.hs.Serve(lis)
	if err != nil {
		log.Printf("start http pprof server err: %s", err)
		return err
	}
	return nil
}

func (p *PProf) Stop() {
	tCtx, tCancel := context.WithTimeout(context.Background(), time.Millisecond*100)
	defer tCancel()
	p.hs.Shutdown(tCtx)
}

func PProfPort(v int) PProfOpt {
	return func(p *pprofConf) {
		p.Port = v
	}
}
