package main

import (
	"crypto/sha1"
	"encoding/hex"
	"encoding/json"
	"fmt"
	"github.com/gin-gonic/gin"
	"io/ioutil"
	"net/http"
	"sort"
	"strings"
)

const (
	token = "your token" // Replace with your actual token
)

func main() {
	router := gin.Default()
	router.POST("/application-demo/postprocess", handlePostprocess)
	router.GET("/application-demo/postprocess", handlePostprocess)
	router.Run(":8080") // Adjust the port if necessary
}

func handlePostprocess(c *gin.Context) {
	switch c.Request.Method {
	case http.MethodPost:
		receiveMessage(c)
	case http.MethodGet:
		serverAccessVerify(c)
	default:
		c.JSON(http.StatusMethodNotAllowed, gin.H{"error": "Method not allowed"})
	}
}

func receiveMessage(c *gin.Context) {
	msgsignature := c.Query("msgsignature")
	timestamp := c.Query("timestamp")
	rand := c.Query("rand")
	body, _ := ioutil.ReadAll(c.Request.Body)
	encryptType := c.Query("encrypttype") // Assuming encryption type passed as a query parameter

	if checkSignature(msgsignature, token, rand, timestamp, string(body)) {
		fmt.Println(">>> 消息验证通过")
	} else {
		fmt.Println(">>> 消息验证未通过")
		c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid message signature"})
		return
	}

	var msg map[string]interface{}
	if encryptType == "raw" {
		json.Unmarshal(body, &msg)
	} else if encryptType == "aes" {
		// Add AES decryption logic here
	}

	// Handle the message based on the content type
	fromSub := msg["FromSub"].(string)
	if fromSub == "iat" {
		c.JSON(http.StatusOK, msg) // Echo back the body for simplicity
	} else if fromSub == "kc" {
		response := handleNlpResult(msg)
		c.JSON(http.StatusOK, response)
	}

}

func handleNlpResult(msg map[string]interface{}) map[string]interface{} {
	// Process NLP result here and construct response
	// This is just an example, adjust based on your actual logic
	intent := msg["intent"].(map[string]interface{})
	answer := intent["answer"].(map[string]interface{})

	response := map[string]interface{}{
		"intent": map[string]interface{}{
			"answer": map[string]interface{}{
				"text": answer["text"],
			},
		},
	}
	return response
}

func serverAccessVerify(c *gin.Context) {
	rand := c.Query("rand")
	timestamp := c.Query("timestamp")
	signature := c.Query("signature")

	if checkSignature(signature, token, rand, timestamp) {
		fmt.Println(">>> 服务器接入验证通过")
		shaToken := sha1Hash(token)
		c.String(http.StatusOK, shaToken)
	} else {
		fmt.Println(">>> 服务器接入验证未通过")
		c.JSON(http.StatusBadRequest, gin.H{"error": "Access verification failed"})
	}
}

func checkSignature(signature string, args ...string) bool {
	sort.Strings(args)
	signString := strings.Join(args, "")
	computedSignature := sha1Hash(signString)
	return signature == computedSignature
}

func sha1Hash(input string) string {
	h := sha1.New()
	h.Write([]byte(input))
	bs := h.Sum(nil)
	return hex.EncodeToString(bs)
}
