package main

import (
	"flag"
	"fmt"
	"github.com/fsnotify/fsnotify"
	"strings"
	"time"
)

var GWatcher *Watcher

func InitWatcher(paths []string) {
	GWatcher = NewWatcher(paths)
}

type Watcher struct {
	operators []func(fsnotify.Event)
	watcher   map[string]*fsnotify.Watcher
}

func NewWatcher(paths []string) *Watcher {
	watcherMap := make(map[string]*fsnotify.Watcher)
	for _, path := range paths {
		watcher, _ := fsnotify.NewWatcher()
		watcherMap[path] = watcher
	}
	return &Watcher{
		watcher: watcherMap,
	}
}
func (w *Watcher) RegistOperator(operator func(fsnotify.Event)) {
	w.operators = append(w.operators, operator)
	fmt.Printf("add operator, %p \n", operator)
}

func (w *Watcher) Run() {
	for path := range w.watcher {
		go w.runWatcher(path, w.watcher[path])
	}
}

func (w *Watcher) runWatcher(path string, watcher *fsnotify.Watcher) {
	fmt.Printf("path %s, start to run \n", path)
	done := make(chan bool)
	go func() {
		for {
			select {
			case event := <-watcher.Events:
				fmt.Println("emit:", event.String())
				for _, op := range w.operators {
					go op(event)
				}
			case err := <-watcher.Errors:
				fmt.Println("Error:", err)
			}
		}
	}()
	_ = watcher.Add(path)
	<-done
}

var path_ = flag.String("p", ".", "path")

func main() {
	flag.Parse()
	paths := strings.Split(*path_, ";")
	fmt.Println(paths)
	InitWatcher(paths) // 初始化watcher,输入路径列表

	GWatcher.Run()
	time.Sleep(time.Second * 10)

	// 注册通知方法
	GWatcher.RegistOperator(Op3)
	GWatcher.RegistOperator(Op2)
	GWatcher.RegistOperator(Op1)

	time.Sleep(20 * time.Minute)
}

func Op1(e fsnotify.Event) {
	fmt.Println("in op1", e.Op.String(), e.Name)
}
func Op2(e fsnotify.Event) {
	fmt.Println("in op2", e.Op.String(), e.Name)
}
func Op3(e fsnotify.Event) {
	fmt.Println("in op3", e.Op.String(), e.Name)
}