package containertest

import (
	"crypto/rand"

	"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/container"
	netmaptest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/netmap/test"
	refstest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/refs/test"
	sessiontest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/session/test"
)

func GenerateAttribute(empty bool) *container.Attribute {
	m := new(container.Attribute)

	if !empty {
		m.SetKey("key")
		m.SetValue("val")
	}

	return m
}

func GenerateAttributes(empty bool) []container.Attribute {
	var res []container.Attribute

	if !empty {
		res = append(res,
			*GenerateAttribute(false),
			*GenerateAttribute(false),
		)
	}

	return res
}

func GenerateContainer(empty bool) *container.Container {
	m := new(container.Container)

	if !empty {
		nonce := make([]byte, 16)
		_, _ = rand.Read(nonce)

		m.SetBasicACL(12)
		m.SetNonce(nonce)
		m.SetOwnerID(refstest.GenerateOwnerID(false))
		m.SetAttributes(GenerateAttributes(false))
		m.SetPlacementPolicy(netmaptest.GeneratePlacementPolicy(false))
	}

	m.SetVersion(refstest.GenerateVersion(empty))

	return m
}

func GeneratePutRequestBody(empty bool) *container.PutRequestBody {
	m := new(container.PutRequestBody)

	if !empty {
		m.SetContainer(GenerateContainer(false))
	}

	m.SetSignature(refstest.GenerateSignature(empty))

	return m
}

func GeneratePutRequest(empty bool) *container.PutRequest {
	m := new(container.PutRequest)

	if !empty {
		m.SetBody(GeneratePutRequestBody(false))
	}

	m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
	m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))

	return m
}

func GeneratePutResponseBody(empty bool) *container.PutResponseBody {
	m := new(container.PutResponseBody)

	if !empty {
		m.SetContainerID(refstest.GenerateContainerID(false))
	}

	return m
}

func GeneratePutResponse(empty bool) *container.PutResponse {
	m := new(container.PutResponse)

	if !empty {
		m.SetBody(GeneratePutResponseBody(false))
	}

	m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
	m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))

	return m
}

func GenerateGetRequestBody(empty bool) *container.GetRequestBody {
	m := new(container.GetRequestBody)

	if !empty {
		m.SetContainerID(refstest.GenerateContainerID(false))
	}

	return m
}

func GenerateGetRequest(empty bool) *container.GetRequest {
	m := new(container.GetRequest)

	if !empty {
		m.SetBody(GenerateGetRequestBody(false))
	}

	m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
	m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))

	return m
}

func GenerateGetResponseBody(empty bool) *container.GetResponseBody {
	m := new(container.GetResponseBody)

	if !empty {
		m.SetContainer(GenerateContainer(false))
	}

	m.SetSignature(refstest.GenerateSignature(empty))
	m.SetSessionToken(sessiontest.GenerateSessionToken(empty))

	return m
}

func GenerateGetResponse(empty bool) *container.GetResponse {
	m := new(container.GetResponse)

	if !empty {
		m.SetBody(GenerateGetResponseBody(false))
	}

	m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
	m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))

	return m
}

func GenerateDeleteRequestBody(empty bool) *container.DeleteRequestBody {
	m := new(container.DeleteRequestBody)

	if !empty {
		m.SetContainerID(refstest.GenerateContainerID(false))
	}

	m.SetSignature(refstest.GenerateSignature(empty))

	return m
}

func GenerateDeleteRequest(empty bool) *container.DeleteRequest {
	m := new(container.DeleteRequest)

	if !empty {
		m.SetBody(GenerateDeleteRequestBody(false))
	}

	m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
	m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))

	return m
}

func GenerateDeleteResponseBody(_ bool) *container.DeleteResponseBody {
	m := new(container.DeleteResponseBody)

	return m
}

func GenerateDeleteResponse(empty bool) *container.DeleteResponse {
	m := new(container.DeleteResponse)

	if !empty {
		m.SetBody(GenerateDeleteResponseBody(false))
	}

	m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
	m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))

	return m
}

func GenerateListRequestBody(empty bool) *container.ListRequestBody {
	m := new(container.ListRequestBody)

	if !empty {
		m.SetOwnerID(refstest.GenerateOwnerID(false))
	}

	return m
}

func GenerateListRequest(empty bool) *container.ListRequest {
	m := new(container.ListRequest)

	if !empty {
		m.SetBody(GenerateListRequestBody(false))
	}

	m.SetMetaHeader(sessiontest.GenerateRequestMetaHeader(empty))
	m.SetVerificationHeader(sessiontest.GenerateRequestVerificationHeader(empty))

	return m
}

func GenerateListResponseBody(empty bool) *container.ListResponseBody {
	m := new(container.ListResponseBody)

	if !empty {
		m.SetContainerIDs(refstest.GenerateContainerIDs(false))
	}

	return m
}

func GenerateListResponse(empty bool) *container.ListResponse {
	m := new(container.ListResponse)

	if !empty {
		m.SetBody(GenerateListResponseBody(false))
	}

	m.SetMetaHeader(sessiontest.GenerateResponseMetaHeader(empty))
	m.SetVerificationHeader(sessiontest.GenerateResponseVerificationHeader(empty))

	return m
}