package apemanager

import (
	apemanager "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/apemanager/grpc"
	"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/message"
	"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/util/proto"
)

const (
	addChainReqBodyTargetField = 1
	addChainReqBodyChainField  = 2

	addChainRespBodyChainIDField = 1

	removeChainReqBodyTargetField = 1
	removeChainReqBodyChainField  = 2

	/*
		Fields for RemoveResponseBody are missed since RemoveResponseBody is empty.
	*/

	listChainsReqBodyTargetField = 1

	listChainsRespBodyChainsField = 1
)

func (rb *AddChainRequestBody) StableSize() (size int) {
	if rb == nil {
		return 0
	}

	size += proto.NestedStructureSize(addChainReqBodyTargetField, rb.target)
	size += proto.NestedStructureSize(addChainReqBodyChainField, rb.chain)

	return size
}

func (rb *AddChainRequestBody) StableMarshal(buf []byte) []byte {
	if rb == nil {
		return []byte{}
	}

	if buf == nil {
		buf = make([]byte, rb.StableSize())
	}

	var offset int

	offset += proto.NestedStructureMarshal(addChainReqBodyTargetField, buf[offset:], rb.target)
	proto.NestedStructureMarshal(addChainReqBodyChainField, buf[offset:], rb.chain)

	return buf
}

func (rb *AddChainRequestBody) Unmarshal(data []byte) error {
	return message.Unmarshal(rb, data, new(apemanager.AddChainRequest_Body))
}

func (rb *AddChainResponseBody) StableSize() (size int) {
	if rb == nil {
		return 0
	}

	size += proto.BytesSize(addChainRespBodyChainIDField, rb.chainID)

	return size
}

func (rb *AddChainResponseBody) StableMarshal(buf []byte) []byte {
	if rb == nil {
		return []byte{}
	}

	if buf == nil {
		buf = make([]byte, rb.StableSize())
	}

	var offset int

	proto.BytesMarshal(addChainRespBodyChainIDField, buf[offset:], rb.chainID)

	return buf
}

func (rb *AddChainResponseBody) Unmarshal(data []byte) error {
	return message.Unmarshal(rb, data, new(apemanager.AddChainResponse_Body))
}

func (rb *RemoveChainRequestBody) StableSize() (size int) {
	if rb == nil {
		return 0
	}

	size += proto.NestedStructureSize(addChainReqBodyTargetField, rb.target)
	size += proto.BytesSize(addChainReqBodyChainField, rb.chainID)

	return size
}

func (rb *RemoveChainRequestBody) StableMarshal(buf []byte) []byte {
	if rb == nil {
		return []byte{}
	}

	if buf == nil {
		buf = make([]byte, rb.StableSize())
	}

	var offset int

	offset += proto.NestedStructureMarshal(removeChainReqBodyTargetField, buf[offset:], rb.target)
	proto.BytesMarshal(removeChainReqBodyChainField, buf[offset:], rb.chainID)

	return buf
}

func (rb *RemoveChainRequestBody) Unmarshal(data []byte) error {
	return message.Unmarshal(rb, data, new(apemanager.RemoveChainRequest_Body))
}

func (rb *RemoveChainResponseBody) StableSize() (size int) {
	if rb == nil {
		return 0
	}

	return size
}

func (rb *RemoveChainResponseBody) StableMarshal(buf []byte) []byte {
	if rb == nil {
		return []byte{}
	}

	if buf == nil {
		buf = make([]byte, rb.StableSize())
	}

	return buf
}

func (rb *RemoveChainResponseBody) Unmarshal(data []byte) error {
	return message.Unmarshal(rb, data, new(apemanager.RemoveChainResponse_Body))
}

func (rb *ListChainsRequestBody) StableSize() (size int) {
	if rb == nil {
		return 0
	}

	size += proto.NestedStructureSize(listChainsReqBodyTargetField, rb.target)

	return size
}

func (rb *ListChainsRequestBody) StableMarshal(buf []byte) []byte {
	if rb == nil {
		return []byte{}
	}

	if buf == nil {
		buf = make([]byte, rb.StableSize())
	}

	var offset int
	proto.NestedStructureMarshal(addChainReqBodyTargetField, buf[offset:], rb.target)

	return buf
}

func (rb *ListChainsRequestBody) Unmarshal(data []byte) error {
	return message.Unmarshal(rb, data, new(apemanager.ListChainsRequest_Body))
}

func (rb *ListChainsResponseBody) StableSize() (size int) {
	if rb == nil {
		return 0
	}

	for _, chain := range rb.GetChains() {
		size += proto.NestedStructureSize(listChainsRespBodyChainsField, chain)
	}

	return size
}

func (rb *ListChainsResponseBody) StableMarshal(buf []byte) []byte {
	if rb == nil {
		return []byte{}
	}

	if buf == nil {
		buf = make([]byte, rb.StableSize())
	}

	var offset int
	for _, chain := range rb.GetChains() {
		offset += proto.NestedStructureMarshal(listChainsRespBodyChainsField, buf[offset:], chain)
	}

	return buf
}

func (rb *ListChainsResponseBody) Unmarshal(data []byte) error {
	return message.Unmarshal(rb, data, new(apemanager.ListChainsResponse_Body))
}