package test

import (
	"archive/zip"
	"fmt"
	"io"
	"os"
	"path/filepath"
	"strings"
	"testing"
)

func TestZip(t *testing.T) {
	src := "C:\\Users\\mlxengingin\\Desktop\\0813\\go从入门到通天(20)"
	dest := "C:\\Users\\mlxengingin\\Desktop\\0813\\go从入门到通天(20).zip"
	excludeDir := "C:\\Users\\mlxengingin\\Desktop\\0813\\go从入门到通天(20)\\搜索引擎" // 你想排除的子目录
	err := ZipDir(src, dest, excludeDir)
	if err != nil {
		fmt.Println("Error:", err)
		return
	}
	fmt.Println("Zip created successfully:", dest)
}

// 压缩指定目录到ZIP文件,并排除一个指定的子目录
func ZipDir(src, dest, excludeDir string) error {
	zipf, err := os.Create(dest)
	if err != nil {
		return err
	}
	defer zipf.Close()

	archive := zip.NewWriter(zipf)
	defer archive.Close()

	filepath.Walk(src, func(path string, info os.FileInfo, err error) error {
		if err != nil {
			return err
		}

		header, err := zip.FileInfoHeader(info)
		if err != nil {
			return err
		}

		// 修正文件路径,使其相对于src
		header.Name, err = filepath.Rel(src, path)
		if err != nil {
			return err
		}

		// 如果路径包含要排除的目录,则跳过
		if strings.Contains(header.Name, excludeDir) {
			if info.IsDir() {
				return filepath.SkipDir // 如果是目录,则跳过整个目录
			}
			return nil // 如果是文件,则忽略该文件
		}

		if info.IsDir() {
			header.Name += "/"
		} else {
			header.Method = zip.Deflate
		}

		writer, err := archive.CreateHeader(header)
		if err != nil {
			return err
		}

		if !info.IsDir() {
			file, err := os.Open(path)
			if err != nil {
				return err
			}
			defer file.Close()
			_, err = io.Copy(writer, file)
			return err
		}
		return nil
	})

	return nil
}