/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2025-2026. All rights reserved.
 * KubernetesPlugin is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 * http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

// Package main run matrix controller
package main

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

	"matrixplugin/pkg/constant"
	"matrixplugin/pkg/escapealarm/controller"
	"matrixplugin/pkg/health"
	"matrixplugin/pkg/utils/log"
)

const (
	delayExitSecond = 3 * time.Second // delay to exit
)

var (
	exitFunc = func(code int) {
		os.Exit(code)
	}
	healthz = flag.Bool("healthz", false, "Run liveness checks")
)

func main() {
	log.GetLogger().Info("matrix controller start...")
	flag.Parse()
	// Start Liveness Probe Client
	if *healthz {
		err := health.RunHealthCheck(constant.MatrixControllerHealthSocketPath)
		if err != nil {
			log.GetLogger().Errorf(err.Error())
			os.Exit(1)
		}
		os.Exit(0)
	}
	// Start Liveness Probe Server
	err := health.StartUdsServer(constant.MatrixControllerHealthSocketPath)
	if err != nil {
		logAndExit(err.Error(), constant.StartUdsServerFailedCode)
		return
	}
	ctx, cancel := context.WithCancel(context.Background())
	err = controller.ContainerEscapeAlarm(ctx)
	if err != nil {
		logAndExit(err.Error(), constant.InitEscapeAlarmExitCode)
		return
	}

	sigCh := make(chan os.Signal, 1)
	signal.Notify(sigCh, os.Interrupt, syscall.SIGTERM)

	waitCh := make(chan os.Signal, 1)

	go func() {
		<-sigCh
		log.GetLogger().Info("recv SIGTERM signal...")
		cancel()
		waitCh <- syscall.SIGTERM
	}()

	waitForSignalNotify(waitCh)
	log.GetLogger().Info("matrix controller shutdown with system call.")
	time.Sleep(delayExitSecond)
}

func logAndExit(msg string, code int) {
	log.GetLogger().Errorf(msg)
	exitFunc(code)
}

func waitForSignalNotify(c <-chan os.Signal) {
	<-c
}