package local

import (
	"fmt"

	cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
	oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
	"git.frostfs.info/TrueCloudLab/xk6-frostfs/internal/local/rawclient"
	"github.com/dop251/goja"
	"go.k6.io/k6/js/modules"
)

type Client struct {
	vu modules.VU
	rc *rawclient.RawClient
}

type (
	SuccessOrErrorResponse struct {
		Success bool
		Error   string
	}

	PutResponse struct {
		Success  bool
		ObjectID string
		Error    string
	}

	GetResponse    SuccessOrErrorResponse
	DeleteResponse SuccessOrErrorResponse
)

func (c *Client) Put(containerID string, headers map[string]string, payload goja.ArrayBuffer) PutResponse {
	id, err := c.rc.Put(c.vu.Context(), mustParseContainerID(containerID), nil, headers, payload.Bytes())
	if err != nil {
		return PutResponse{Error: err.Error()}
	}
	return PutResponse{
		Success:  true,
		ObjectID: id.EncodeToString(),
	}
}

func (c *Client) Get(containerID, objectID string) GetResponse {
	if _, err := c.rc.Get(c.vu.Context(), mustParseContainerID(containerID), mustParseObjectID(objectID)); err != nil {
		return GetResponse{Error: err.Error()}
	}
	return GetResponse{Success: true}
}

func (c *Client) Delete(containerID, objectID string) DeleteResponse {
	if err := c.rc.Delete(c.vu.Context(), mustParseContainerID(containerID), mustParseObjectID(objectID)); err != nil {
		return DeleteResponse{Error: err.Error()}
	}
	return DeleteResponse{Success: true}
}

func mustParseContainerID(strContainerID string) cid.ID {
	var containerID cid.ID
	err := containerID.DecodeString(strContainerID)
	if err != nil {
		panic(fmt.Sprintf("parsing container id %q: %v", strContainerID, err))
	}
	return containerID
}

func mustParseObjectID(strObjectID string) oid.ID {
	var cliObjectID oid.ID
	err := cliObjectID.DecodeString(strObjectID)
	if err != nil {
		panic(fmt.Sprintf("parsing object id %q: %v", strObjectID, err))
	}
	return cliObjectID
}