package main

import (
	"fmt"
	"html/template"
	"io"
	"log"
	"net/http/cgi"
	"os"
	"os/user"
	"path"
	"syno-common/server/sso"
	"syno-common/server/utils"
)

func main() {
	// Todo:
	// fix-up error handling with correct http responses (add --debug flag?/Synology's notifications?)
	// worry about csrf
	//dev = flag.Bool("dev", false, "Turns Authentication checks off")
	//flag.Parse()

	curDir := utils.GetCurDir()
	var logF *os.File
	var err error

	logF, err = os.OpenFile(fmt.Sprintf("%v/commontools.log", curDir), os.O_CREATE|os.O_APPEND|os.O_RDWR, os.ModePerm)
	if err == nil {
		defer func() {
			logF.Close()
		}()
		log.SetOutput(logF)
	}
	log.Println("initLog end")
	log.Println("initLog end", curDir)
	u, _ := user.Current()
	if u != nil {
		log.Println("user", u)
	}

	req, err := cgi.Request()
	if err != nil {
		log.Println("request fail", err)
		utils.LogError("request fail!")
	}

	var method = os.Getenv("REQUEST_METHOD")
	action := req.URL.Query().Get("action")
	log.Println("req: ", method, action)
	if method == "GET" {
		RenderHTML("update.html")
		log.Println("simple h5")
		return
	}

	file, head, err := req.FormFile("file")
	if err != nil {
		log.Println("no files form is nil ", err)
		utils.LogError("file is required!")
	}
	filenameWithSuffix := path.Base(head.Filename)
	log.Println("filename", filenameWithSuffix)
	uploadDir := path.Join(curDir, "uploads")
	if !utils.FileIsExist(uploadDir) {
		os.MkdirAll(uploadDir, 0777)
	}
	filePath := path.Join(uploadDir, filenameWithSuffix)
	localFile, err := os.Create(filePath)
	if err != nil {
		log.Println("create file err", err)
		utils.LogError("create file err")
	}
	defer localFile.Close()
	_, err = io.Copy(localFile, file)
	if err != nil {
		log.Println("copy file err", err)
		utils.LogError("copy file err")
	}

	if action == "portal" {
		dstDir := path.Join(curDir, "web")
		err = utils.Unzip(filePath, dstDir)
		if err != nil {
			log.Println("unzip fail", err)
			utils.LogError("unzip fail")
		}
	}

	utils.RespData(sso.RespJSON{
		Data: filenameWithSuffix,
		Code: 1,
		Msg:  "success",
	})
}

func RenderHTML(filename string) {
	fmt.Print("Status: 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n")

	htmlDir := path.Join(utils.GetCurDir(), "html")
	if !utils.FileIsExist(htmlDir) {
		htmlDir = path.Join(utils.GetCurDir(), "../", "html")
	}
	absPath := path.Join(htmlDir, filename)
	if !utils.FileIsExist(absPath) {
		utils.LogError("filename not exist ", filename)
	}
	log.Println("template path", absPath)

	temp, err := template.ParseFiles(absPath)
	if err != nil {
		utils.LogError("ParseFiles error ", err.Error())
	}

	data := map[string]any{}

	//var writer = StringWriter{}
	err = temp.Execute(os.Stdout, data)
	if err != nil {
		log.Println("execute fail", err)
		//utils.LogError("internal error")
	}
	//log.Println(writer.ToString())
	//fmt.Print(writer.ToString())
}

type StringWriter struct {
	Data []byte
	Len  int
}

func (s *StringWriter) Write(p []byte) (n int, err error) {
	s.Data = append(s.Data, p...)
	s.Len = s.Len + len(p)
	fmt.Println("Write", len(p))
	return s.Len, nil
}
func (s *StringWriter) ToString() string {
	return string(s.Data)
}
