package main

//nolint:staticcheck
import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strings"
	"syscall"
	"time"

	"ciyon/web/admin/autotask"
	c "ciyon/zciyon"

	_ "github.com/go-sql-driver/mysql"
)

func main() {
	//nohup ./zgo &
	//nohup /data/go/ciyon/zgo > /dev/null 2>&1 &
	c.CiyVars.Version = "1.0.2"
	c.Clog("---=========================Ciyon=========================---")
	c.Clog("Version:", c.CiyVars.Version, " WorkDir:", c.CiyWebDir)
	//读取配置文件ini

	ini, err3 := c.NewCiyINI("web.ini")
	c.CiyVars.Ini = *ini
	runmode := "dev"
	logfile := "log/ciyon.log"
	logtcp := ""
	logfilelevel := 3
	logtcplevel := 3

	webmode := "http"  //Web服务模式: http/fastcgi/unixsock
	webipsk := ":4003" //Web监听端口: ip:port/unix:sockfile
	webhttp2 := ""     //启用HTTP2：配置监听端口,证书.crt,证书.key :443,w.crt,w.key
	dbhost := "127.0.0.1"
	dbport := "3306"
	dbuser := "root"
	dbpass := "wkxroot"
	dbname := "techciyon"
	dbmaxopenconn := 0
	dbmaxidelconn := 0
	dbmaxlifesec := 0
	phphost := ""
	tasksec := 5
	mock := "" //支持file，建立本地文件夹
	if err3 != nil {
		ini.SetKey("main", "runmode", runmode)
		ini.SetKey("main", "tasksec", tasksec)
		ini.SetKey("log", "logfile", logfile)
		ini.SetKey("log", "logtcp", logtcp)
		ini.SetKey("log", "logfilelevel", logfilelevel)
		ini.SetKey("log", "logtcplevel", logtcplevel)

		ini.SetKey("web", "webmode", webmode)
		ini.SetKey("web", "webipsk", webipsk)
		ini.SetKey("web", "webhttp2", webhttp2)
		ini.SetKey("db", "host", dbhost)
		ini.SetKey("db", "post", dbport)
		ini.SetKey("db", "user", dbuser)
		ini.SetKey("db", "pass", dbpass)
		ini.SetKey("db", "name", dbname)
		ini.SetKey("db", "maxopenconn", dbmaxopenconn)
		ini.SetKey("db", "maxidelconn", dbmaxidelconn)
		ini.SetKey("db", "maxlifesec", dbmaxlifesec)
		ini.SetKey("php", "host", phphost)
		ini.SetKey("mock", "target", mock)
		ini.Save()
	} else {
		runmode = ini.GetKey("main", "runmode", runmode)
		if runmode == "prod" {
			c.CiyRunMode = c.CIYRUN_PROD
		} else {
			c.CiyRunMode = c.CIYRUN_DEV
		}
		tasksec = ini.GetKeyint("main", "tasksec", tasksec)
		logfile = ini.GetKey("log", "logfile", logfile)
		logtcp = ini.GetKey("log", "logtcp", logtcp)
		logfilelevel = ini.GetKeyint("log", "logfilelevel", logfilelevel)
		logtcplevel = ini.GetKeyint("log", "logtcplevel", logtcplevel)

		webmode = ini.GetKey("web", "webmode", webmode)
		webipsk = ini.GetKey("web", "webipsk", webipsk)
		webhttp2 = ini.GetKey("web", "webhttp2", webhttp2)
		dbhost = ini.GetKey("db", "host", dbhost)
		dbport = ini.GetKey("db", "post", dbport)
		dbuser = ini.GetKey("db", "user", dbuser)
		dbpass = ini.GetKey("db", "pass", dbpass)
		dbname = ini.GetKey("db", "name", dbname)
		dbmaxopenconn = ini.GetKeyint("db", "maxopenconn", dbmaxopenconn)
		dbmaxidelconn = ini.GetKeyint("db", "maxidelconn", dbmaxidelconn)
		dbmaxlifesec = ini.GetKeyint("db", "maxlifesec", dbmaxlifesec)
		phphost = ini.GetKey("php", "host", phphost)
		mock = ini.GetKey("mock", "target", mock)
	}
	c.Log = c.NewCiyLog(500)
	c.Log.SupportStack(c.CiyVars.Version)
	c.Log.InitFile(logfile, logfilelevel)
	c.Log.InitTCP(logtcp, logtcplevel)
	c.Log.Info("Ciyon", "Ciyon Start.")
	go watchMe()

	// Log.Debug("sdfs", "asfsdfasdf")

	var err error
	// CiyRouteDB, err = NewCiyDBRoute([]string{"root:wkxroot@tcp(localhost:3306)/zosa"}, 0, 0, 0) //main初始化一直开
	// if err != nil {
	// 	log.Fatal(err)
	// }
	c.CiyDB, err = c.NewCiyMysql(fmt.Sprintf("%s:%s@tcp(%s)/%s", dbuser, dbpass, dbhost+":"+dbport, dbname), dbmaxopenconn, dbmaxidelconn, dbmaxlifesec) //main初始化一直开着，程序结束才关
	if err != nil {
		log.Fatal(err)
	}

	web, err2 := c.NewCiyWebServer()
	if err2 != nil {
		log.Fatal(err2)
	}
	// web.SetExt(".html;.js")
	// web.RouterStatic("/jscss/")
	setWebRoute_adm(web)
	//setWebRoute_work(web)

	//内网php网站，端口8080，golang端口4003，nginx80/443将goc指向golang，golang根据情况转发给8080处理。
	//将golang包放在网站根目录下。
	web.SetPHP(phphost)
	if mock == "file" {
		web.SetMockFile() //在web/ud/mock目录下建立对应的json文件。
	} else if mock != "" {
		web.SetMockFn(func(w http.ResponseWriter, r *http.Request) error {
			funname := r.URL.Path
			funs := strings.Split(funname, ".")
			if len(funs) < 2 {
				return fmt.Errorf("func fmterr func=%v", funname)
			}
			csql := c.NewCiySQL(mock)
			csql.Where("upath", funs[0])
			csql.Where("ufunc", funs[1])
			mockrow, _ := c.CiyDB.Getone(csql)
			if mockrow == nil {
				return fmt.Errorf("nofind mock func=%v", funname)
			}
			mockjson := c.Tostr(mockrow["mockjson"])
			quest := r.URL.RawQuery
			body, err := io.ReadAll(r.Body)
			if err == nil && len(body) > 0 {
				quest += "\n" + string(body)
			}
			if mockjson[0:7] == "http://" {
				resp, err := http.Post(mockjson, "application/json", r.Body)
				if err != nil {
					return err
				}
				defer resp.Body.Close()
				w.Header().Set("Content-Type", resp.Header.Get("Content-Type"))
				w.WriteHeader(resp.StatusCode)
				io.Copy(w, resp.Body)

			} else {
				w.Write([]byte(mockjson))
			}
			updata := map[string]any{
				"lastrequest": quest,
				"lasttimes":   c.Tostamp(),
			}
			csql = c.NewCiySQL(mock)
			csql.Where("id", mockrow["id"])
			c.CiyDB.Update(csql, updata)
			return nil
		})
	}

	if c.CiyRunMode == c.CIYRUN_DEV {
		tasksec = 0
	}
	if tasksec > 0 {
		go doautotask(tasksec)
	}

	go web.RunHTTP2(webhttp2)
	web.Run(webmode, webipsk)
	//web.WebRunCgi(7002)
	//web.WebRunHTTP2(80, 443, "testgo.crt", "testgo.key")
	//web.WebRunSock("ciyon.sock")
}
func watchMe() {
	fmd5 := c.MD5file(os.Args[0])
	for {
		newfmd5 := c.MD5file(os.Args[0])
		if newfmd5 != fmd5 {
			c.Sleep(1)
			fmt.Println("restarting:")
			c.Log.Info("RESTART", "Restarting.."+newfmd5)
			err := syscall.Exec(os.Args[0], os.Args, os.Environ())
			if err != nil {
				fmt.Println("restart fail:", err)
				c.Log.Info("RESTART", "重启失败:"+err.Error())
				c.Sleep(10)
				continue
			}
			os.Exit(0)
			return
		}
		c.Sleep(2)
		continue
	}
}
func doautotask(sec int) {
	ticker := time.NewTicker(time.Duration(sec) * time.Second)
	defer ticker.Stop()
	for range ticker.C {
		go autotask.Main()
	}
}
