package compress

import (
	"bytes"
	"compress/gzip"
	"encoding/json"
	"io"
	"os"
)

// DoGzip 压缩bytes内容到指定文件
func DoGzip(content []byte, path string, fileName string) error {
	gzFile, err := os.Create(path)
	if err != nil {
		return err
	}
	defer gzFile.Close()
	gzipWriter := gzip.NewWriter(gzFile)

	defer gzipWriter.Close()
	gzipWriter.Name = fileName
	_, err = gzipWriter.Write(content)
	if err != nil {
		return err
	}
	return nil
}

// UnGzip 解压文件
func UnGzip(path string) (content []byte, err error) {
	gzipFile, err := os.Open(path)
	if err != nil {
		return
	}
	defer gzipFile.Close()
	gzipReader, err := gzip.NewReader(gzipFile)
	if err != nil {
		return
	}
	defer gzipReader.Close()
	var buf bytes.Buffer
	_, err = io.Copy(&buf, gzipReader)
	if err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}

func GzipEncode(input []byte) ([]byte, error) {
	// 创建一个新的 byte 输出流
	var buf bytes.Buffer
	// 创建一个新的 gzip 输出流

	//NoCompression      = flate.NoCompression      // 不压缩
	//BestSpeed          = flate.BestSpeed          // 最快速度
	//BestCompression    = flate.BestCompression    // 最佳压缩比
	//DefaultCompression = flate.DefaultCompression // 默认压缩比
	//gzip.NewWriterLevel()
	gzipWriter := gzip.NewWriter(&buf)

	defer gzipWriter.Close()

	// 将 input byte 数组写入到此输出流中
	_, err := gzipWriter.Write(input)
	if err != nil {
		return nil, err
	}

	// 返回压缩后的 bytes 数组
	return buf.Bytes(), nil
}

func GzipDecode(input []byte) ([]byte, error) {
	// 创建一个新的 gzip.Reader
	bytesReader := bytes.NewReader(input)
	gzipReader, err := gzip.NewReader(bytesReader)
	if err != nil {
		return nil, err
	}
	defer gzipReader.Close()
	buf := new(bytes.Buffer)
	// 从 Reader 中读取出数据
	if _, err := buf.ReadFrom(gzipReader); err != nil {
		return nil, err
	}

	return buf.Bytes(), nil
}

// MarshalJsonAndGzip 压缩字符
func MarshalJsonAndGzip(data interface{}) ([]byte, error) {
	marshalData, err := json.Marshal(data)
	if err != nil {
		return nil, err
	}
	gzipData, err := GzipEncode(marshalData)
	if err != nil {
		return nil, err
	}
	return gzipData, err
}

// UnmarshalDataFromJsonWithGzip 解压字符
func UnmarshalDataFromJsonWithGzip(input []byte, output interface{}) error {
	decodeData, err := GzipDecode(input)
	if err != nil {
		return err
	}

	err = json.Unmarshal(decodeData, output)
	if err != nil {
		return err
	}
	return nil
}
