package cmd

import (
	"context"
	"fmt"
	"folder_monitoring/config"
	"folder_monitoring/global"
	"folder_monitoring/mq"
	"folder_monitoring/store"
	"github.com/spf13/cobra"
	"go.uber.org/zap"
	"os"
	"os/signal"
	"path/filepath"
	"syscall"
)

var (
	ConfigFileFlag string = "./config/config.yaml"
	NodeName       string = "main-node"
	Mode           string = "dev"
	Path           string = "" //监控文件夹
)

func must(err error) {
	if err != nil {
		_, _ = fmt.Fprint(os.Stderr, err)
		os.Exit(1)
	}
}

func NewStartCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "start",
		Short: "Start folder monitor",
		Run: func(cmd *cobra.Command, args []string) {
			var (
				cfg *config.FolderMonitorConfig
				err error
			)
			ctx, cancel := context.WithCancel(context.Background())
			defer cancel()
			must(err)
			configFileFlag, err := cmd.Flags().GetString("c")
			if err != nil {
				fmt.Println("get local config err: ", err)
				return
			}

			NodeName, err = cmd.Flags().GetString("n")
			if err != nil {
				fmt.Println("get remote path config err: ", err)
				return
			}
			Mode, err = cmd.Flags().GetString("m")
			if err != nil {
				fmt.Println("get remote path config err: ", err)
				return
			}
			if len(configFileFlag) > 1 {
				cfg, err = config.ParseConfigByFile(configFileFlag)
				must(err)
				cfg.MonitorPath, _ = filepath.Abs(cfg.MonitorPath)
				cfg.TempPath, _ = filepath.Abs(cfg.TempPath)
				ConfigFileFlag = configFileFlag
			}
			global.Cfg = cfg
			global.Logger = config.LoadLoggerConfig(cfg.Logging)
			//加载历史文件的传输情况
			err = store.Load(cfg.TempPath, global.FileHistoryMap)
			must(err)
			//创建消息连接点
			mq.MqList, err = mq.NewMqClient(cfg.Funcs, cfg.Node, global.Logger)
			must(err)
			if b, _ := store.PathExists(cfg.MonitorPath); !b {
				_ = os.MkdirAll(cfg.MonitorPath, os.ModePerm)
			}
			//初始化全局
			global.InitWatchFolder(cfg.MonitorPath)
			must(err)
			// 退出channel
			exitChannel := make(chan os.Signal)
			defer close(exitChannel)
			// 退出信号监听
			go func(c chan os.Signal) {
				signal.Notify(c, syscall.SIGINT, syscall.SIGTERM)
			}(exitChannel)
			//开始监控
			go global.WatchEvent()
			//go func() {
			//	for {
			//		select {
			//		case ev := <-global.Watch.Events:
			//			if ev.Op&fsnotify.Create == fsnotify.Create {
			//				logging.L().Info("创建文件", zap.String("文件名", ev.Name))
			//				global.FileList.Add(ev.Name)
			//			}
			//		case <-t1.C:
			//			{
			//				if global.FileList.Size() > 0 {
			//				}
			//			}
			//		case err := <-global.Watch.Errors:
			//			{
			//				log.Println("error : ", err)
			//				return
			//			}
			//	}
			//}()
			select {
			case <-ctx.Done():
				global.Logger.With(
					zap.String(cfg.Name, "exit"),
				).Error(ctx.Err().Error())
				return
			case errs := <-exitChannel:
				store.Save(cfg.TempPath, global.FileHistoryMap)
				global.Logger.With(
					zap.String(cfg.Name, "服务退出"),
				).Info(errs.String())
				os.Exit(-1)
				return
			}
		},
	}
	cmd.Flags().StringVar(&ConfigFileFlag, "c", "./config/config.yaml", "The configuration file path")
	cmd.Flags().StringVar(&NodeName, "n", "main-node", "The configuration name")
	cmd.Flags().StringVar(&Mode, "m", "dev", "run mode : dev | test | releases")
	cmd.Flags().StringVar(&Path, "f", "", "monitor folder path")
	return cmd
}
