package main

import (
	"bytes"
	"encoding/json"
	"fmt"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"os"
	"path/filepath"
	"strings"
	"time"
)

const (
	baseURL = "http://localhost:6902/api"
)

// App 结构体定义
 type App struct {
	ID       string `json:"id"`
	Name     string `json:"name"`
	FileName string `json:"fileName"`
	Date     string `json:"date"`
}

// 获取App列表
func getApps() ([]App, error) {
	resp, err := http.Get(baseURL + "/apps")
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}

	var apps []App
	if err := json.Unmarshal(body, &apps); err != nil {
		return nil, err
	}

	return apps, nil
}

// 上传App
func uploadApp(name, filePath string) (bool, error) {
	// 打开文件
	file, err := os.Open(filePath)
	if err != nil {
		return false, err
	}
	defer file.Close()

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

	// 添加name字段
	writer.WriteField("name", name)

	// 添加file字段
	part, err := writer.CreateFormFile("file", filepath.Base(filePath))
	if err != nil {
		return false, err
	}

	// 复制文件内容到表单
	if _, err := io.Copy(part, file); err != nil {
		return false, err
	}

	writer.Close()

	// 创建请求
	req, err := http.NewRequest("POST", baseURL+"/apps", body)
	if err != nil {
		return false, err
	}
	req.Header.Set("Content-Type", writer.FormDataContentType())

	// 发送请求
	resp, err := http.DefaultClient.Do(req)
	if err != nil {
		return false, err
	}
	defer resp.Body.Close()

	// 解析响应
	respBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return false, err
	}

	var response map[string]bool
	if err := json.Unmarshal(respBody, &response); err != nil {
		return false, err
	}

	return response["success"], nil
}

// 下载App
func downloadApp(id string) ([]byte, error) {
	resp, err := http.Get(baseURL + "/apps/" + id)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		body, _ := ioutil.ReadAll(resp.Body)
		return nil, fmt.Errorf("download failed: %s, %s", resp.Status, string(body))
	}

	return ioutil.ReadAll(resp.Body)
}

// 测试上传和下载功能
func testUploadDownload() error {
	// 获取当前目录下的fake_files目录
	fakeFilesDir := "fake_files"

	// 读取fake_files目录下的所有文件
	files, err := ioutil.ReadDir(fakeFilesDir)
	if err != nil {
		return err
	}

	// 上传每个文件
	for _, file := range files {
		if file.IsDir() {
			continue
		}

		filePath := filepath.Join(fakeFilesDir, file.Name())
		appName := strings.TrimSuffix(file.Name(), filepath.Ext(file.Name()))

		fmt.Printf("Uploading %s...\n", file.Name())
		success, err := uploadApp(appName, filePath)
		if err != nil {
			return fmt.Errorf("failed to upload %s: %v", file.Name(), err)
		}
		if !success {
			return fmt.Errorf("upload %s failed", file.Name())
		}
		fmt.Printf("Uploaded %s successfully\n", file.Name())

		// 等待一下，避免并发问题
		time.Sleep(100 * time.Millisecond)
	}

	// 获取App列表
	apps, err := getApps()
	if err != nil {
		return fmt.Errorf("failed to get apps: %v", err)
	}

	fmt.Printf("\nTotal %d apps uploaded:\n", len(apps))
	for _, app := range apps {
		fmt.Printf("- %s (%s)\n", app.Name, app.FileName)
	}

	// 测试下载第一个App
	if len(apps) > 0 {
		fmt.Printf("\nDownloading %s...\n", apps[0].FileName)
		data, err := downloadApp(apps[0].ID)
		if err != nil {
			return fmt.Errorf("failed to download %s: %v", apps[0].FileName, err)
		}
		fmt.Printf("Downloaded %s successfully, size: %d bytes\n", apps[0].FileName, len(data))
	}

	return nil
}

// 测试文件覆盖情况
func testFileOverwrite() error {
	// 上传同一个文件两次，测试是否会覆盖
	filePath := "fake_files/empty.txt"
	appName := "Test Overwrite"

	fmt.Printf("\nTesting file overwrite...\n")

	// 第一次上传
	fmt.Printf("First upload of %s...\n", filePath)
	success, err := uploadApp(appName, filePath)
	if err != nil {
		return fmt.Errorf("first upload failed: %v", err)
	}
	if !success {
		return fmt.Errorf("first upload returned false")
	}

	// 第二次上传
	fmt.Printf("Second upload of %s...\n", filePath)
	success, err = uploadApp(appName+" 2", filePath)
	if err != nil {
		return fmt.Errorf("second upload failed: %v", err)
	}
	if !success {
		return fmt.Errorf("second upload returned false")
	}

	// 获取App列表，应该有两个不同ID的App，但文件名相同
	apps, err := getApps()
	if err != nil {
		return fmt.Errorf("failed to get apps: %v", err)
	}

	fmt.Printf("\nAfter two uploads, total %d apps:\n", len(apps))
	emptyTxtApps := 0
	for _, app := range apps {
		if app.FileName == "empty.txt" {
			emptyTxtApps++
			fmt.Printf("- %s (%s) [ID: %s]\n", app.Name, app.FileName, app.ID)
		}
	}

	fmt.Printf("\nFound %d apps with filename 'empty.txt'\n", emptyTxtApps)
	if emptyTxtApps != 2 {
		return fmt.Errorf("expected 2 apps with filename 'empty.txt', got %d", emptyTxtApps)
	}

	return nil
}

func main() {
	fmt.Println("Testing app distribution backend...")

	// 等待服务启动
	fmt.Println("\nWaiting for server to start...")
	time.Sleep(2 * time.Second)

	// 测试上传下载功能
	if err := testUploadDownload(); err != nil {
		fmt.Printf("Error in testUploadDownload: %v\n", err)
		return
	}

	// 测试文件覆盖情况
	if err := testFileOverwrite(); err != nil {
		fmt.Printf("Error in testFileOverwrite: %v\n", err)
		return
	}

	fmt.Println("\nAll tests passed successfully!")
}