// Code generated by smithy-go-codegen DO NOT EDIT.

//go:build response_snapshot

package smithyrpcv2cborquerycompatible

import (
	"context"
	"errors"
	"github.com/aws/aws-sdk-go-v2/internal/protocoltest/smithyrpcv2cborquerycompatible/schemas"
	"github.com/aws/aws-sdk-go-v2/internal/protocoltest/smithyrpcv2cborquerycompatible/types"
	smithy "github.com/aws/smithy-go"
	smithycbor "github.com/aws/smithy-go/encoding/cbor"
	smithyhttp "github.com/aws/smithy-go/transport/http"
	"github.com/aws/smithy-go/transport/http/protocol/rpcv2"
	"io"
	"io/fs"
	"net/http"
	"os"
	"slices"
	"strconv"
	"strings"
	"testing"
)

func serdeRespCreatePath(path string) (*os.File, error) {
	if err := os.MkdirAll(serdeRespSSPrefix, 0700); err != nil && !errors.Is(err, fs.ErrExist) {
		return nil, err
	}
	return os.Create(path)
}

func serdeRespWriteSnapshot(op string, status int, header http.Header, body []byte) error {
	f, err := serdeRespCreatePath(serdeRespSSPath(op))
	if err != nil {
		return err
	}
	defer f.Close()

	var sb strings.Builder
	sb.WriteString(strconv.Itoa(status))
	sb.WriteString("\n")
	keys := make([]string, 0, len(header))
	for k := range header {
		keys = append(keys, k)
	}
	slices.Sort(keys)
	for _, k := range keys {
		for _, v := range header[k] {
			sb.WriteString(k)
			sb.WriteString(": ")
			sb.WriteString(v)
			sb.WriteString("\n")
		}
	}
	sb.WriteString("\n")
	sb.Write(body)
	_, err = f.WriteString(sb.String())
	return err
}

// serdeRespXMLErrorEnvelope wraps serialized error members in the XML
// error envelope the restXml/query deserializers parse:
// <ErrorResponse><Error><Code>CODE</Code>MEMBERS</Error></ErrorResponse>.
// It strips the serialized body's outer root element and re-parents the
// members under <Error>.
func serdeRespXMLErrorEnvelope(body []byte, code string) []byte {
	inner := ""
	s := strings.TrimSpace(string(body))
	if strings.HasPrefix(s, "<?xml") {
		if i := strings.Index(s, "?>"); i >= 0 {
			s = strings.TrimSpace(s[i+2:])
		}
	}
	if start := strings.Index(s, ">"); start >= 0 {
		if end := strings.LastIndex(s, "<"); end > start {
			inner = s[start+1 : end]
		}
	}
	return []byte("<ErrorResponse><Error><Code>" + code + "</Code>" + inner + "</Error></ErrorResponse>")
}
func TestUpdateResponseSnapshot_GetItem(t *testing.T) {
	want := &GetItemOutput{}
	proto := rpcv2.NewCBOR(schemas.RpcV2CborQueryCompatible)
	opSchema := smithy.NewOperationSchema(schemas.GetItem, schemas.GetItemOutput, schemas.GetItemOutput)
	req := smithyhttp.NewStackRequest().(*smithyhttp.Request)
	if err := proto.SerializeRequest(context.Background(), opSchema, want, req); err != nil {
		t.Fatal(err)
	}
	built := req.Build(context.Background())
	var body []byte
	if built.Body != nil {
		b, err := io.ReadAll(built.Body)
		if err != nil {
			t.Fatal(err)
		}
		body = b
	}
	if err := serdeRespWriteSnapshot("GetItem.response", 200, built.Header, body); err != nil {
		t.Fatal(err)
	}
}

func TestUpdateResponseSnapshot_Error_ItemNotFound(t *testing.T) {
	want := &types.ItemNotFound{}
	proto := rpcv2.NewCBOR(schemas.RpcV2CborQueryCompatible)
	opSchema := smithy.NewOperationSchema(schemas.GetItem, schemas.ItemNotFound, schemas.ItemNotFound)
	req := smithyhttp.NewStackRequest().(*smithyhttp.Request)
	if err := proto.SerializeRequest(context.Background(), opSchema, want, req); err != nil {
		t.Fatal(err)
	}
	built := req.Build(context.Background())
	var body []byte
	if built.Body != nil {
		b, err := io.ReadAll(built.Body)
		if err != nil {
			t.Fatal(err)
		}
		body = b
	}
	// Inject the CBOR error discriminator into the body map so the deserializer routes to the
	// modeled error type.
	var m smithycbor.Map
	if len(body) > 0 {
		v, err := smithycbor.Decode(body)
		if err != nil {
			t.Fatal(err)
		}
		mm, ok := v.(smithycbor.Map)
		if !ok {
			t.Fatalf("expected cbor map body, got %T", v)
		}
		m = mm
	} else {
		m = smithycbor.Map{}
	}
	m["__type"] = smithycbor.String(want.ErrorCode())
	body = smithycbor.Encode(m)
	if err := serdeRespWriteSnapshot("ItemNotFound.error", 400, built.Header, body); err != nil {
		t.Fatal(err)
	}
}
