package sentry

import (
	"github.com/getsentry/sentry-go"
	"github.com/pingcap/dbaas/billing2/config"
	"github.com/pingcap/log"

	"github.com/pingcap/dbaas/billing2/utils/sentry/zapsentry"
	"github.com/pingcap/errors"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

func setupLogger(opts ...zap.Option) error {
	cfg := &log.Config{
		Level: "info",
	}
	gl, props, err := log.InitLogger(cfg, append(opts, zap.AddStacktrace(zapcore.ErrorLevel))...)
	if err != nil {
		return errors.Trace(err)
	}
	log.ReplaceGlobals(gl, props)

	return nil
}

func setupSentry() error {
	sentryServerDSN := config.Get().GetString(config.SentryServerDSN)
	sentryServerEnv := config.Get().GetString(config.SentryServerEnv)
	opts := sentry.ClientOptions{
		Dsn:         sentryServerDSN,
		Environment: sentryServerEnv,
	}
	if err := sentry.Init(opts); err != nil {
		log.Error("setupSentry failed", zap.String("dsn", sentryServerDSN), zap.String("env", sentryServerEnv))
		return err
	}
	return nil
}

func SetupLoggerAndSentry() error {
	enable := config.Get().GetBool(config.EnableSentryLog)
	if !enable {
		return nil
	}
	if err := setupSentry(); err != nil {
		return errors.Annotate(err, "setupSentry failed")
	}
	var level zapcore.Level
	if err := level.UnmarshalText([]byte(config.Get().GetString(config.SentryLogLevel))); err != nil {
		return errors.Annotate(err, "invalid sentry.LogLevel")
	}
	sentryOpt := zap.WrapCore(func(core zapcore.Core) zapcore.Core {
		return zapcore.NewTee(core, zapsentry.NewCore(level, sentry.CurrentHub().Client()))
	})

	err := setupLogger(sentryOpt)
	if err != nil {
		return errors.Annotate(err, "initialize logger failed")
	}

	return nil
}

func CaptureError(err error) {
	sentry.CaptureException(err)
}
