package main

import (
	"bytes"
	"fmt"
	"io"
	"mime/multipart"
	"net/http"
	"os"
	"path/filepath"
	"sync"
	"time"
)

const (
	baseURL = "http://localhost:6902/api"
	concurrency = 10 // 并发数
)

// 并发上传文件
func concurrentUploads(wg *sync.WaitGroup, filePaths []string, results chan<- string) {
	defer wg.Done()

	for _, filePath := range filePaths {
		// 打开文件
		file, err := os.Open(filePath)
		if err != nil {
			results <- fmt.Sprintf("Error opening file %s: %v", filePath, err)
			continue
		}
		defer file.Close()

		// 创建multipart表单
		body := &bytes.Buffer{}
		writer := multipart.NewWriter(body)

		// 添加name字段
		appName := filepath.Base(filePath)
		writer.WriteField("name", appName)

		// 添加file字段
		part, err := writer.CreateFormFile("file", filepath.Base(filePath))
		if err != nil {
			results <- fmt.Sprintf("Error creating form file %s: %v", filePath, err)
			continue
		}

		// 复制文件内容
		_, err = io.Copy(part, file)
		if err != nil {
			results <- fmt.Sprintf("Error copying file content %s: %v", filePath, err)
			continue
		}

		writer.Close()

		// 创建请求
		req, err := http.NewRequest("POST", baseURL+"/apps", body)
		if err != nil {
			results <- fmt.Sprintf("Error creating request for %s: %v", filePath, err)
			continue
		}
		req.Header.Set("Content-Type", writer.FormDataContentType())

		// 发送请求
		resp, err := http.DefaultClient.Do(req)
		if err != nil {
			results <- fmt.Sprintf("Error sending request for %s: %v", filePath, err)
			continue
		}
		resp.Body.Close()

		if resp.StatusCode == http.StatusOK {
			results <- fmt.Sprintf("Successfully uploaded %s", filePath)
		} else {
			results <- fmt.Sprintf("Failed to upload %s, status: %d", filePath, resp.StatusCode)
		}

		// 等待一下，避免请求过于密集
		time.Sleep(50 * time.Millisecond)
	}
}

// 并发获取App列表
func concurrentGetApps(wg *sync.WaitGroup, results chan<- string) {
	defer wg.Done()

	for i := 0; i < 5; i++ {
		resp, err := http.Get(baseURL + "/apps")
		if err != nil {
			results <- fmt.Sprintf("Error getting apps: %v", err)
			continue
		}
		resp.Body.Close()

		if resp.StatusCode == http.StatusOK {
			results <- "Successfully got apps list"
		} else {
			results <- fmt.Sprintf("Failed to get apps list, status: %d", resp.StatusCode)
		}

		// 等待一下，避免请求过于密集
		time.Sleep(50 * time.Millisecond)
	}
}

func main() {
	fmt.Println("Starting concurrent test...")
	startTime := time.Now()

	// 获取测试文件列表
	testFiles := []string{
		"fake_files/empty.txt",
		"fake_files/fake_file_0_4.txt",
	}

	// 创建结果通道
	results := make(chan string, 100)

	// 创建WaitGroup
	var wg sync.WaitGroup

	// 启动并发上传协程
	for i := 0; i < concurrency; i++ {
		wg.Add(1)
		go concurrentUploads(&wg, testFiles, results)
	}

	// 启动并发获取App列表协程
	for i := 0; i < concurrency/2; i++ {
		wg.Add(1)
		go concurrentGetApps(&wg, results)
	}

	// 等待所有协程完成
	wg.Wait()
	close(results)

	// 打印结果
	fmt.Println("\nTest Results:")
	successCount := 0
	errorCount := 0
	for result := range results {
		fmt.Println(result)
		if len(result) > 8 && result[:8] == "Successfully" {
			successCount++
		} else {
			errorCount++
		}
	}

	// 打印统计信息
	totalTime := time.Since(startTime)
	fmt.Printf("\nTest Statistics:")
	fmt.Printf("\n- Total requests: %d", successCount+errorCount)
	fmt.Printf("\n- Successful requests: %d", successCount)
	fmt.Printf("\n- Failed requests: %d", errorCount)
	fmt.Printf("\n- Total time: %v", totalTime)
	fmt.Printf("\n- Requests per second: %.2f\n", float64(successCount+errorCount)/totalTime.Seconds())

	if errorCount == 0 {
		fmt.Println("\n✅ All concurrent requests succeeded! System is stable.")
	} else {
		fmt.Printf("\n❌ %d concurrent requests failed. System may have stability issues.", errorCount)
	}
}