package apemanager

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

func (reqBody *AddChainRequestBody) ToGRPCMessage() grpc.Message {
	var reqBodygrpc *apemanager.AddChainRequest_Body

	if reqBody != nil {
		reqBodygrpc = new(apemanager.AddChainRequest_Body)

		reqBodygrpc.SetTarget(reqBody.GetTarget().ToGRPCMessage().(*apeGRPC.ChainTarget))
		reqBodygrpc.SetChain(reqBody.GetChain().ToGRPCMessage().(*apeGRPC.Chain))
	}

	return reqBodygrpc
}

func (reqBody *AddChainRequestBody) FromGRPCMessage(m grpc.Message) error {
	reqBodygrpc, ok := m.(*apemanager.AddChainRequest_Body)
	if !ok {
		return message.NewUnexpectedMessageType(m, reqBodygrpc)
	}

	if targetgrpc := reqBodygrpc.GetTarget(); targetgrpc != nil {
		reqBody.target = new(ape.ChainTarget)
		if err := reqBody.target.FromGRPCMessage(targetgrpc); err != nil {
			return err
		}
	}

	if chaingrpc := reqBodygrpc.GetChain(); chaingrpc != nil {
		reqBody.chain = new(ape.Chain)
		if err := reqBody.GetChain().FromGRPCMessage(chaingrpc); err != nil {
			return err
		}
	}

	return nil
}

func (req *AddChainRequest) ToGRPCMessage() grpc.Message {
	var reqgrpc *apemanager.AddChainRequest

	if req != nil {
		reqgrpc = new(apemanager.AddChainRequest)

		reqgrpc.SetBody(req.GetBody().ToGRPCMessage().(*apemanager.AddChainRequest_Body))
		req.RequestHeaders.ToMessage(reqgrpc)
	}

	return reqgrpc
}

func (req *AddChainRequest) FromGRPCMessage(m grpc.Message) error {
	reqgrpc, ok := m.(*apemanager.AddChainRequest)
	if !ok {
		return message.NewUnexpectedMessageType(m, reqgrpc)
	}

	if reqBodygrpc := reqgrpc.GetBody(); reqBodygrpc != nil {
		req.body = new(AddChainRequestBody)
		if err := req.body.FromGRPCMessage(reqBodygrpc); err != nil {
			return err
		}
	}

	return req.RequestHeaders.FromMessage(reqgrpc)
}

func (respBody *AddChainResponseBody) ToGRPCMessage() grpc.Message {
	var respBodygrpc *apemanager.AddChainResponse_Body

	if respBody != nil {
		respBodygrpc = new(apemanager.AddChainResponse_Body)

		respBodygrpc.SetChainId(respBody.GetChainID())
	}

	return respBodygrpc
}

func (respBody *AddChainResponseBody) FromGRPCMessage(m grpc.Message) error {
	respBodygrpc, ok := m.(*apemanager.AddChainResponse_Body)
	if !ok {
		return message.NewUnexpectedMessageType(m, respBodygrpc)
	}

	respBody.SetChainID(respBodygrpc.GetChainId())

	return nil
}

func (resp *AddChainResponse) ToGRPCMessage() grpc.Message {
	var respgrpc *apemanager.AddChainResponse

	if resp != nil {
		respgrpc = new(apemanager.AddChainResponse)

		respgrpc.SetBody(resp.body.ToGRPCMessage().(*apemanager.AddChainResponse_Body))
		resp.ResponseHeaders.ToMessage(respgrpc)
	}

	return respgrpc
}

func (resp *AddChainResponse) FromGRPCMessage(m grpc.Message) error {
	respgrpc, ok := m.(*apemanager.AddChainResponse)
	if !ok {
		return message.NewUnexpectedMessageType(m, respgrpc)
	}

	if respBodygrpc := respgrpc.GetBody(); respBodygrpc != nil {
		resp.body = new(AddChainResponseBody)
		if err := resp.body.FromGRPCMessage(respBodygrpc); err != nil {
			return err
		}
	}

	return resp.ResponseHeaders.FromMessage(respgrpc)
}

func (reqBody *RemoveChainRequestBody) ToGRPCMessage() grpc.Message {
	var reqBodygrpc *apemanager.RemoveChainRequest_Body

	if reqBody != nil {
		reqBodygrpc = new(apemanager.RemoveChainRequest_Body)

		reqBodygrpc.SetTarget(reqBody.target.ToGRPCMessage().(*apeGRPC.ChainTarget))
		reqBodygrpc.SetChainId(reqBody.GetChainID())
	}

	return reqBodygrpc
}

func (reqBody *RemoveChainRequestBody) FromGRPCMessage(m grpc.Message) error {
	reqBodygrpc, ok := m.(*apemanager.RemoveChainRequest_Body)
	if !ok {
		return message.NewUnexpectedMessageType(m, reqBodygrpc)
	}

	if targetgrpc := reqBodygrpc.GetTarget(); targetgrpc != nil {
		reqBody.target = new(ape.ChainTarget)
		if err := reqBody.target.FromGRPCMessage(targetgrpc); err != nil {
			return err
		}
	}

	reqBody.SetChainID(reqBodygrpc.GetChainId())

	return nil
}

func (req *RemoveChainRequest) ToGRPCMessage() grpc.Message {
	var reqgrpc *apemanager.RemoveChainRequest

	if req != nil {
		reqgrpc = new(apemanager.RemoveChainRequest)

		reqgrpc.SetBody(req.body.ToGRPCMessage().(*apemanager.RemoveChainRequest_Body))
		req.RequestHeaders.ToMessage(reqgrpc)
	}

	return reqgrpc
}

func (req *RemoveChainRequest) FromGRPCMessage(m grpc.Message) error {
	reqgrpc, ok := m.(*apemanager.RemoveChainRequest)
	if !ok {
		return message.NewUnexpectedMessageType(m, reqgrpc)
	}

	if reqBodygrpc := reqgrpc.GetBody(); reqBodygrpc != nil {
		req.body = new(RemoveChainRequestBody)
		if err := req.body.FromGRPCMessage(reqBodygrpc); err != nil {
			return err
		}
	}

	return req.RequestHeaders.FromMessage(reqgrpc)
}

func (respBody *RemoveChainResponseBody) ToGRPCMessage() grpc.Message {
	var respBodygrpc *apemanager.RemoveChainResponse_Body

	if respBody != nil {
		respBodygrpc = new(apemanager.RemoveChainResponse_Body)
	}

	return respBodygrpc
}

func (respBody *RemoveChainResponseBody) FromGRPCMessage(m grpc.Message) error {
	respBodygrpc, ok := m.(*apemanager.RemoveChainResponse_Body)
	if !ok {
		return message.NewUnexpectedMessageType(m, respBodygrpc)
	}

	return nil
}

func (resp *RemoveChainResponse) ToGRPCMessage() grpc.Message {
	var respgrpc *apemanager.RemoveChainResponse

	if resp != nil {
		respgrpc = new(apemanager.RemoveChainResponse)

		respgrpc.SetBody(resp.body.ToGRPCMessage().(*apemanager.RemoveChainResponse_Body))
		resp.ResponseHeaders.ToMessage(respgrpc)
	}

	return respgrpc
}

func (resp *RemoveChainResponse) FromGRPCMessage(m grpc.Message) error {
	respgrpc, ok := m.(*apemanager.RemoveChainResponse)
	if !ok {
		return message.NewUnexpectedMessageType(m, respgrpc)
	}

	if respBodygrpc := respgrpc.GetBody(); respBodygrpc != nil {
		resp.body = new(RemoveChainResponseBody)
		if err := resp.body.FromGRPCMessage(respBodygrpc); err != nil {
			return err
		}
	}

	return resp.ResponseHeaders.FromMessage(respgrpc)
}

func (reqBody *ListChainsRequestBody) ToGRPCMessage() grpc.Message {
	var reqBodygrpc *apemanager.ListChainsRequest_Body

	if reqBody != nil {
		reqBodygrpc = new(apemanager.ListChainsRequest_Body)

		reqBodygrpc.SetTarget(reqBody.target.ToGRPCMessage().(*apeGRPC.ChainTarget))
	}

	return reqBodygrpc
}

func (reqBody *ListChainsRequestBody) FromGRPCMessage(m grpc.Message) error {
	reqBodygrpc, ok := m.(*apemanager.ListChainsRequest_Body)
	if !ok {
		return message.NewUnexpectedMessageType(m, reqBodygrpc)
	}

	if targetgrpc := reqBodygrpc.GetTarget(); targetgrpc != nil {
		reqBody.target = new(ape.ChainTarget)
		if err := reqBody.target.FromGRPCMessage(targetgrpc); err != nil {
			return err
		}
	}

	return nil
}

func (req *ListChainsRequest) ToGRPCMessage() grpc.Message {
	var reqgrpc *apemanager.ListChainsRequest

	if req != nil {
		reqgrpc = new(apemanager.ListChainsRequest)

		reqgrpc.SetBody(req.body.ToGRPCMessage().(*apemanager.ListChainsRequest_Body))
		req.RequestHeaders.ToMessage(reqgrpc)
	}

	return reqgrpc
}

func (req *ListChainsRequest) FromGRPCMessage(m grpc.Message) error {
	reqgrpc, ok := m.(*apemanager.ListChainsRequest)
	if !ok {
		return message.NewUnexpectedMessageType(m, reqgrpc)
	}

	if reqBodygrpc := reqgrpc.GetBody(); reqBodygrpc != nil {
		req.body = new(ListChainsRequestBody)
		if err := req.body.FromGRPCMessage(reqBodygrpc); err != nil {
			return err
		}
	}

	return req.RequestHeaders.FromMessage(reqgrpc)
}

func (respBody *ListChainsResponseBody) ToGRPCMessage() grpc.Message {
	var respBodygrpc *apemanager.ListChainsResponse_Body

	if respBody != nil {
		respBodygrpc = new(apemanager.ListChainsResponse_Body)

		chainsgrpc := make([]apeGRPC.Chain, 0, len(respBody.GetChains()))
		for _, chain := range respBody.GetChains() {
			chainsgrpc = append(chainsgrpc, *chain.ToGRPCMessage().(*apeGRPC.Chain))
		}

		respBodygrpc.SetChains(chainsgrpc)
	}

	return respBodygrpc
}

func (respBody *ListChainsResponseBody) FromGRPCMessage(m grpc.Message) error {
	respBodygrpc, ok := m.(*apemanager.ListChainsResponse_Body)
	if !ok {
		return message.NewUnexpectedMessageType(m, respBodygrpc)
	}

	chains := make([]*ape.Chain, 0, len(respBodygrpc.GetChains()))

	for _, chaingrpc := range respBodygrpc.GetChains() {
		chain := new(ape.Chain)
		if err := chain.FromGRPCMessage(&chaingrpc); err != nil {
			return err
		}
		chains = append(chains, chain)
	}

	respBody.SetChains(chains)

	return nil
}

func (resp *ListChainsResponse) ToGRPCMessage() grpc.Message {
	var respgrpc *apemanager.ListChainsResponse

	if resp != nil {
		respgrpc = new(apemanager.ListChainsResponse)

		respgrpc.SetBody(resp.body.ToGRPCMessage().(*apemanager.ListChainsResponse_Body))
		resp.ResponseHeaders.ToMessage(respgrpc)
	}

	return respgrpc
}

func (resp *ListChainsResponse) FromGRPCMessage(m grpc.Message) error {
	respgrpc, ok := m.(*apemanager.ListChainsResponse)
	if !ok {
		return message.NewUnexpectedMessageType(m, respgrpc)
	}

	if respBodygrpc := respgrpc.GetBody(); respBodygrpc != nil {
		resp.body = new(ListChainsResponseBody)
		if err := resp.body.FromGRPCMessage(respBodygrpc); err != nil {
			return err
		}
	}

	return resp.ResponseHeaders.FromMessage(respgrpc)
}