package main

import (
	"fmt"
	"log"
	"net/http"
	"net/http/httputil"
	"net/url"
	"strconv"
	"time"
)

//PathsConfig all system available pathes
type PathsConfig struct {
	Angular2App string `json:"angular2_app"`
}

//TODO: setup GlobalPath Config, from reading file
//GlobalPath all global pathes configurations
var GlobalPath = PathsConfig{
	"/mnt/data/workspace/angular.ts/wechat/ng2-admin/dist/"}

//KFUsers info cache about current customer service
var KFUsers kfCache

func main() {
	err := readConfig() //wechat API config
	if err != nil {
		log.Println(err)
		log.Fatal("unable to read server_config.json, program quit")
		return
	}

	err = readCRMConfig()
	if err != nil {
		log.Println(err)
		log.Fatal("unable to read crm_config.json, program quit")
	}

	err = IntraAPIConfig.readConfig()
	if err != nil {
		log.Println(err)
		log.Fatal("unable to read intra-api-config, program quit")
	}

	initAllProc()
	setupRootFileServer()
	startSessionManager(2048)
	KFUsers.kfRenewList()
	//always the last one
	setupHTTPHandler()

}

func setupHTTPHandler() {
	//setup handler
	//http.HandleFunc("/", webrootHandler)
	http.HandleFunc("/api", apiV1Main)
	http.HandleFunc("/upload", uploadHandler)
	http.HandleFunc("/crmfiles/", crmAttachmentHandler)
	http.HandleFunc("/dumprequest", dumpReuestHandler)
	http.HandleFunc("/MP_verify_6JqVkftKr39GMakA.txt", mpDomainAuthSecret)
	http.HandleFunc("/redirect", setTrackingCookieAndRecirect)
	http.HandleFunc("/iapi/getAccessToken", supplyAccessToken)
	http.HandleFunc("/iapi/createWechatQr", iapiCreateWechatQrCode)
	http.HandleFunc("/crmpixel.png", crmpixel) //tracking pixel.
	http.HandleFunc("/crmcache", crmcache)
	http.ListenAndServe(":65500", nil)
}

func startSessionManager(concurrent int) {
	m := SessionManager{}
	AllInMessage = make(chan *InWechatMsg, concurrent)
	go m.startSessionManager(AllInMessage)
}

func setupRootFileServer() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		http.ServeFile(w, r, GlobalPath.Angular2App+r.URL.Path[1:])
	})

	//fs := http.FileServer(http.Dir("/mnt/data/workspace/angular.ts/ng2-admin/dist"))
	//http.Handle("/test", http.StripPrefix("/test", fs))

	//fs := http.FileServer(http.Dir("/mnt/data/workspace/angular.ts/wechat/ng2-admin/dist"))
	//http.Handle("/", fs)
}

func dumpReuestHandler(w http.ResponseWriter, r *http.Request) {
	logRequestDebug(httputil.DumpRequest(r, true))
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	w.Header().Set("Access-Control-Allow-Origin", "http://192.168.1.39:4200")
	w.Header().Set("Access-Control-Allow-Headers", "Authorziation11,Authorziation12")
	w.Header().Set("Access-Control-Allow-Credentials", "true")
	w.Header().Set("Access-Control-Expose-Headers", "Set-Cookie,myheader,*")
	w.Header().Set("myheader", "myheader-data")

	expiration := time.Now().Add(10 * 365 * 24 * time.Hour)
	str := time.Now().String()
	cookie := http.Cookie{Name: "username", Value: str, Expires: expiration}
	http.SetCookie(w, &cookie)

	fmt.Fprintf(w, `{"status":"OK"}`)
	for _, c := range r.Cookies() {
		log.Println(c.Name)
		log.Println(c.Value)
	}
}

func supplyAccessToken(w http.ResponseWriter, r *http.Request) {
	//logRequestDebug(httputil.DumpRequest(r, true))
	if checkSignatureByToken(r, IntraAPIConfig.CRMSecrete) {
		atk, _ := GetAccessToken()
		fmt.Fprint(w, atk)
	} else {
		w.WriteHeader(401)
		fmt.Fprint(w, "unauthorized")
	}
}

func iapiCreateWechatQrCode(w http.ResponseWriter, r *http.Request) {
	logRequestDebug(httputil.DumpRequest(r, true))
	if !checkSignatureByToken(r, IntraAPIConfig.CRMSecrete) {
		w.WriteHeader(http.StatusUnauthorized)
		fmt.Fprint(w, "unauthorized")
		return
	}
	rq := r.URL.RawQuery
	m, _ := url.ParseQuery(rq)

	qrValue, qok := m["qrValue"]
	expire, eok := m["expire"]

	if !qok || !eok {
		w.WriteHeader(http.StatusUnprocessableEntity)
		fmt.Fprintf(w, "parameter not correct, bad api call %s", time.Now().Format(getCrmTimeLayout()))
		return
	}

	if isStrInt(qrValue[0]) && isStrInt(expire[0]) {
		intVal, _ := strconv.Atoi(qrValue[0])
		intExpire, _ := strconv.Atoi(expire[0])
		jsonB, err := iapiCreateTempQr(int32(intVal), int32(intExpire))
		if err == nil {
			w.Write(jsonB)
		} else {
			fmt.Fprintf(w, "%s", err)
		}
		return
	}

	if !isStrInt(qrValue[0]) && expire[0] == "0" {
		jsonB, err := isapiCreatePermQr(qrValue[0])
		if err == nil {
			w.Write(jsonB)
		} else {
			fmt.Fprintf(w, "%s", err)
		}
		return

	}
}

func isStrInt(v string) bool {
	if _, err := strconv.Atoi(v); err == nil {
		return true
	}
	return false
}

// 用户在网页授权页同意授权给公众号后，微信会将授权数据传给一个回调页面，回调页面需在此域名下，以确保安全可靠。
// 注意事项：
// 1、回调页面域名或路径需使用字母、数字及“-”的组合（例：wx.qq.com或wx.qq.com/mp），不支持IP地址、端口号及短链域名。填写的域名或路径需与实际回调URL中的域名或路径相同。
// 2、填写的域名须通过ICP备案的验证。
// 3、将文件MP_verify_6JqVkftKr39GMakA.txt（点击下载）上传至填写域名或路径指向的web服务器（或虚拟主机）的目录（若填写域名，将文件放置在域名根目录下，例如wx.qq.com/MP_verify_6JqVkftKr39GMakA.txt；若填写路径，将文件放置在路径目录下，例如wx.qq.com/mp/MP_verify_6JqVkftKr39GMakA.txt），并确保可以访问。
func mpDomainAuthSecret(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "6JqVkftKr39GMakA")
	//由于需要什么ICP备案，这个功能不能使用
}
