package main

import (
	"fmt"
	"net/http"
	"github.com/gin-gonic/gin"

	"github.com/xuperchain/xuper-sdk-go/v2/account"
	"github.com/xuperchain/xuper-sdk-go/v2/xuper"
)

// 配置跨域函数
func Cors() gin.HandlerFunc {
	return func(c *gin.Context) {
		method := c.Request.Method
                origin := c.Request.Header.Get("Origin")
		if origin != "" {
			c.Header("Access-Control-Allow-Origin", "*")
			c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, UPDATE")
			c.Header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization")
			c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Cache-Control, Content-Language, Content-Type")
			c.Header("Access-Control-Allow-Credentials", "true")
		}
		if method == "OPTIONS" {
			c.AbortWithStatus(http.StatusNoContent)
		}
		c.Next()
	}
}

func main() {
	gin.SetMode(gin.ReleaseMode)
	// 1.创建路由
	r := gin.Default()
	// 开启跨域
	r.Use(Cors())
	// 2.绑定路由规则，执行的函数
	// gin.Context，封装了request和response
	r.POST("/query", func(c *gin.Context) {
        id := c.PostForm("id")
		resp:=queryRecords(id)
		c.JSON(200, gin.H{"resp": resp})
    })
	r.POST("/create", func(c *gin.Context) {
        id := c.PostForm("id")
		desc := c.PostForm("desc")
		account := c.PostForm("account")
		contractAccount := c.PostForm("contractAccount")
		resp:=addRecords(id,desc,account,contractAccount)
		c.JSON(200, gin.H{"resp": resp})
    })
	r.POST("/update", func(c *gin.Context) {
        id := c.PostForm("id")
		desc := c.PostForm("desc")
		account := c.PostForm("account")
		contractAccount := c.PostForm("contractAccount")
		resp:=updateRecords(id,desc,account,contractAccount)
		c.JSON(200, gin.H{"resp": resp})
    })
	r.POST("/addAdmin", func(c *gin.Context) {
        address := c.PostForm("address")
		account := c.PostForm("account")
		contractAccount := c.PostForm("contractAccount")
		resp:=addAdmin(address,account,contractAccount)
		c.JSON(200, gin.H{"resp": resp})
    })
	// 3.监听端口，默认在8080
	// Run("里面不指定端口号默认为8080") 
	r.Run(":8000")
}

func queryRecords(id string) string {
	xuperClient, err := xuper.New("39.156.69.83:37100")
	if err != nil {
		resp:= fmt.Sprintf("new xuper Client error: %v\n", err)
		return resp
	}
	account, err := account.RetrieveAccount("铝 纵 殿 熙 何 云 关 棒 悟 信 析 造", 1)
	if err != nil {
		resp:= fmt.Sprintf("retrieveAccount err: %v\n", err)
		return resp
	}
	var contractName string="antifakecon"
	args := map[string]string{
		"id": id,
	}
	tx, err := xuperClient.QueryWasmContract(account, contractName, "queryRecords", args)
	if err != nil {
		resp:=fmt.Sprintf("query err: %v\n", err)
		return resp
	}
	resp:=fmt.Sprintf("data:%s", tx.ContractResponse.Body)
	return resp
}

func addRecords(id string,desc string,key string,contractAccount string) string {
	xuperClient, err := xuper.New("39.156.69.83:37100")
	if err != nil {
		resp:= fmt.Sprintf("new xuper Client error: %v\n", err)
		return resp
	}
	account, err := account.RetrieveAccount(key, 1)
	if err != nil {
		resp:= fmt.Sprintf("retrieveAccount err: %v\n", err)
		return resp
	}
	err = account.SetContractAccount(contractAccount)
	if err != nil {
		resp:= fmt.Sprintf("setContractAccount err: %v\n", err)
		return resp
	}
	var contractName string="antifakecon"
	args := map[string]string{
		"id": id,
		"desc":desc,
	}
	tx, err := xuperClient.InvokeWasmContract(account, contractName, "createGoods", args)
	if err != nil {
		resp:=fmt.Sprintf("create err: %v\n", err)
		return resp
	}
	resp:=fmt.Sprintf("data:%s TxID:%x", tx.ContractResponse.Body, tx.Tx.Txid)
	return resp
}

func updateRecords(id string,desc string,key string,contractAccount string) string {
	xuperClient, err := xuper.New("39.156.69.83:37100")
	if err != nil {
		resp:= fmt.Sprintf("new xuper Client error: %v\n", err)
		return resp
	}
	account, err := account.RetrieveAccount(key, 1)
	if err != nil {
		resp:= fmt.Sprintf("retrieveAccount err: %v\n", err)
		return resp
	}
	err = account.SetContractAccount(contractAccount)
	if err != nil {
		resp:= fmt.Sprintf("setContractAccount err: %v\n", err)
		return resp
	}
	var contractName string="antifakecon"
	args := map[string]string{
		"id": id,
		"reason":desc,
	}
	tx, err := xuperClient.InvokeWasmContract(account, contractName, "updateGoods", args)
	if err != nil {
		resp:=fmt.Sprintf("update err: %v\n", err)
		return resp
	}
	resp:=fmt.Sprintf("data:%s TxID:%x", tx.ContractResponse.Body, tx.Tx.Txid)
	return resp
}

func addAdmin(address string,key string,contractAccount string) string {
	xuperClient, err := xuper.New("39.156.69.83:37100")
	if err != nil {
		resp:= fmt.Sprintf("new xuper Client error: %v\n", err)
		return resp
	}
	account, err := account.RetrieveAccount(key, 1)
	if err != nil {
		resp:= fmt.Sprintf("retrieveAccount err: %v\n", err)
		return resp
	}
	err = account.SetContractAccount(contractAccount)
	if err != nil {
		resp:= fmt.Sprintf("setContractAccount err: %v\n", err)
		return resp
	}
	var contractName string="antifakecon"
	args := map[string]string{
		"admin": address,
	}
	tx, err := xuperClient.InvokeWasmContract(account, contractName, "addAdmin", args)
	if err != nil {
		resp:=fmt.Sprintf("update err: %v\n", err)
		return resp
	}
	resp:=fmt.Sprintf("data:%s TxID:%x", tx.ContractResponse.Body, tx.Tx.Txid)
	return resp
}