package main

import (
	"bytes"
	"compress/flate"
	"fmt"
	"io"
)

type SE struct {
	w    *flate.Writer
	buf  bytes.Buffer
	sent int
}

func (e *SE) Encode(bgr []byte) ([]byte, error) {
	if _, err := e.w.Write(bgr); err != nil {
		return nil, err
	}
	if err := e.w.Flush(); err != nil {
		return nil, err
	}
	out := make([]byte, len(e.buf.Bytes())-e.sent)
	copy(out, e.buf.Bytes()[e.sent:])
	e.sent = len(e.buf.Bytes())
	return out, nil
}

func (e *SE) Close() ([]byte, error) {
	err := e.w.Close()
	out := make([]byte, len(e.buf.Bytes())-e.sent)
	copy(out, e.buf.Bytes()[e.sent:])
	e.sent = len(e.buf.Bytes())
	return out, err
}

func main() {
	se, _ := NewSE()
	var wire []byte
	for f := 0; f < 3; f++ {
		frame := make([]byte, 300)
		for i := range frame {
			frame[i] = byte(f*7 + i)
		}
		out, _ := se.Encode(frame)
		wire = append(wire, out...)
	}
	final, _ := se.Close()
	wire = append(wire, final...)
	fmt.Println("wire:", len(wire))
	r := flate.NewReader(bytes.NewReader(wire))
	out, err := io.ReadAll(r)
	fmt.Println("decoded:", len(out), "err:", err)
}

func NewSE() (*SE, error) {
	var buf bytes.Buffer
	w, err := flate.NewWriter(&buf, flate.BestSpeed)
	if err != nil {
		return nil, err
	}
	return &SE{w: w, buf: buf}, nil
}
