package main

import (
	"net/http"
	"net/http/httptest"
	"os"
	"path/filepath"
	"strings"
	"testing"
)

// download 是原生「另存为 / 系统打开」真正落盘的那一段，之前零测试。
// 对话框本身要真窗口没法自动化，但下载这段是纯 HTTP + 文件 IO，必须钉住。

func TestDownloadOK(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		_, _ = w.Write([]byte("PK\x03\x04fake docx"))
	}))
	defer srv.Close()

	dst := filepath.Join(t.TempDir(), "r.docx")
	if err := download(srv.URL, dst); err != nil {
		t.Fatalf("下载应成功: %v", err)
	}
	b, err := os.ReadFile(dst)
	if err != nil || string(b) != "PK\x03\x04fake docx" {
		t.Fatalf("落盘内容不对: %q err=%v", b, err)
	}
}

func TestDownloadHTTPError(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusNotFound)
	}))
	defer srv.Close()

	dst := filepath.Join(t.TempDir(), "r.docx")
	err := download(srv.URL, dst)
	if err == nil {
		t.Fatal("404 应该报错")
	}
	if !strings.Contains(err.Error(), "404") {
		t.Errorf("错误里应带状态码，便于用户判断: %v", err)
	}
	// 失败时不该在用户选定的路径上留一个空的/半截的 .docx ——
	// 用户会以为导出成功，双击却打不开。
	if _, statErr := os.Stat(dst); statErr == nil {
		t.Error("下载失败却留下了文件（用户会当成导出成功的空文档）")
	}
}

// io.Copy 中途断开：用户选定路径上不该留半截文件。
func TestDownloadTruncatedLeavesNoFile(t *testing.T) {
	srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Length", "999999") // 声明很长，实际写一点就断
		_, _ = w.Write([]byte("half"))
		if f, ok := w.(http.Flusher); ok {
			f.Flush()
		}
		panic(http.ErrAbortHandler) // 掐断连接
	}))
	defer srv.Close()

	dst := filepath.Join(t.TempDir(), "r.docx")
	if err := download(srv.URL, dst); err == nil {
		t.Fatal("连接中断应该报错")
	}
	if _, statErr := os.Stat(dst); statErr == nil {
		t.Error("中断却留下了半截文件")
	}
}

func TestPing(t *testing.T) {
	if (&App{}).Ping() == "" {
		t.Error("Ping 是前端探活 Go 桥的唯一手段，不能返回空")
	}
}
