package file

import (
	"context"
	"errors"
	"fonchain-fiee/api/files"
	"fonchain-fiee/pkg/service"
	"io"
)

type grpcReaderSeeker struct {
	io.Reader
	io.Seeker
	path          string
	userSpacePath string
	cursor        int64
	length        int64
	FileName      string
}

func (g *grpcReaderSeeker) Seek(offset int64, whence int) (int64, error) {
	var abs int64
	switch whence {
	case io.SeekStart:
		abs = offset
	case io.SeekCurrent:
		abs = g.cursor + offset
	case io.SeekEnd:
		abs = g.length + offset
	default:
		return 0, errors.New("grpc.Reader.Seek: invalid whence")
	}
	if abs < 0 {
		return 0, errors.New("grpc.Reader.Seek: negative position")
	}
	g.cursor = abs
	return abs, nil
}

func (g *grpcReaderSeeker) Read(b []byte) (n int, err error) {
	if g.cursor >= g.length {
		return 0, io.EOF
	}

	data, err := g.getBytesData(len(b))
	if err != nil {
		return 0, err
	}
	n = copy(b, data)
	g.cursor += int64(n)
	return
}

// 通过grpc获取到bytes数据
func (g *grpcReaderSeeker) getBytesData(len int) ([]byte, error) {
	resp, err := service.FilesProvider.ResumableTransfer(context.TODO(), &files.ResumableTransferReq{
		UserSpacePath: g.userSpacePath,
		Path:          g.path,
		Offset:        g.cursor,
		Length:        int64(len),
	})
	if err != nil {
		return nil, err
	}
	return resp.Content, nil
}

// grpc 获取到文件信息
func (g *grpcReaderSeeker) initInfo() error {
	resp, err := service.FilesProvider.Info(context.TODO(), &files.FileInfoReq{
		UserSpacePath: g.userSpacePath,
		Path:          g.path,
	})
	if err != nil {
		return nil
	}
	g.FileName = resp.Name
	g.length = resp.Size
	return err
}

func newGrpcReaderSeeker(userSpacePath string, path string) (*grpcReaderSeeker, error) {
	g := new(grpcReaderSeeker)
	g.userSpacePath = userSpacePath
	g.path = path
	err := g.initInfo()
	if err != nil {
		return nil, err
	}
	return g, nil
}