package oci

import (
	"bytes"
	"encoding/json"
	"io"
	"net/http"

	"github.com/oracle/oci-go-sdk/v65/common"
)

// scimErrorDispatcher 包装 Identity Domains 客户端的 HTTP 派发器。
// IDCS 的错误体是 SCIM 格式（detail 字段），而 SDK 只解析 code/message，
// 直接透传会得到消息为空的 BadErrorResponse；这里把 4xx/5xx 的 SCIM
// 错误体改写成 SDK 可解析的标准形状，让真实原因透出到面板。
type scimErrorDispatcher struct {
	base common.HTTPRequestDispatcher
}

func (d scimErrorDispatcher) Do(req *http.Request) (*http.Response, error) {
	resp, err := d.base.Do(req)
	if err != nil || resp == nil || resp.StatusCode < 400 || resp.Body == nil {
		return resp, err
	}
	body, readErr := io.ReadAll(resp.Body)
	resp.Body.Close()
	if readErr != nil {
		resp.Body = io.NopCloser(bytes.NewReader(nil))
		return resp, nil
	}
	rewritten := rewriteScimError(body)
	resp.Body = io.NopCloser(bytes.NewReader(rewritten))
	resp.ContentLength = int64(len(rewritten))
	resp.Header.Del("Content-Length")
	return resp, nil
}

// rewriteScimError 提取 SCIM 错误的 detail 与 messageId 转成
// {code,message}；不是 SCIM 错误体时原样返回。
func rewriteScimError(body []byte) []byte {
	var scim struct {
		Detail string `json:"detail"`
		Ext    struct {
			MessageID string `json:"messageId"`
		} `json:"urn:ietf:params:scim:api:oracle:idcs:extension:messages:Error"`
	}
	if json.Unmarshal(body, &scim) != nil || scim.Detail == "" {
		return body
	}
	code := scim.Ext.MessageID
	if code == "" {
		code = "IdcsError"
	}
	std, err := json.Marshal(map[string]string{"code": code, "message": scim.Detail})
	if err != nil {
		return body
	}
	return std
}
