// Package main 是 room-service 的进程入口，只负责读取配置、装配应用和托管退出信号。
package main

import (
	"context"
	"flag"
	"log"
	"os"
	"os/signal"
	"syscall"

	"hyapp/pkg/logx"
	"hyapp/services/room-service/internal/app"
	"hyapp/services/room-service/internal/config"
)

// main 只负责装配并启动 room-service 进程。
func main() {
	// config 参数只决定当前进程读取哪份 YAML；服务依赖和协议入口由 internal/app 统一装配。
	configPath := flag.String("config", "services/room-service/configs/config.yaml", "path to room-service config")
	flag.Parse()

	// 配置加载失败直接终止进程，避免以错误的节点 ID、MySQL、Redis 或下游地址启动。
	cfg, err := config.Load(*configPath)
	if err != nil {
		log.Fatal(err)
	}
	if err := logx.Init(cfg.Log.WithRuntimeFields(cfg.ServiceName, cfg.Environment, cfg.NodeID)); err != nil {
		log.Fatal(err)
	}

	// App.New 会建立 MySQL repository、Redis directory、wallet/im gRPC client 和 gRPC server。
	application, err := app.New(cfg)
	if err != nil {
		fatalRuntime("app_new_failed", err)
	}

	// SIGINT/SIGTERM 是正常下线入口，下线时要先进入 draining 再停止 gRPC。
	ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
	defer stop()

	// Run 阻塞在 gRPC listener 上，运行期错误通过 errCh 回到主 goroutine。
	errCh := make(chan error, 1)
	go func() {
		errCh <- application.Run()
	}()

	select {
	case <-ctx.Done():
		// Close 内部会标记 draining、GracefulStop gRPC，并释放下游连接和存储连接。
		application.Close()
	case err := <-errCh:
		if err != nil {
			// gRPC listener 异常退出属于进程级失败，必须暴露给 supervisor。
			fatalRuntime("service_run_failed", err)
		}
	}
}

func fatalRuntime(msg string, err error) {
	logx.Error(context.Background(), msg, err)
	os.Exit(1)
}
