package clients

import (
	"context"
	"crypto/sha256"
	"encoding/hex"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
	"time"
)

func TestVolcesAssetClientSignsCreateAndReadsAsset(t *testing.T) {
	var calls []string
	server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		calls = append(calls, r.URL.Query().Get("Action"))
		if r.Method != http.MethodPost || r.URL.Path != "/" || r.URL.Query().Get("Version") != "2024-01-01" {
			t.Fatalf("unexpected asset request %s %s?%s", r.Method, r.URL.Path, r.URL.RawQuery)
		}
		if r.Header.Get("X-Date") != "20260718T010203Z" {
			t.Fatalf("unexpected x-date: %q", r.Header.Get("X-Date"))
		}
		if !strings.HasPrefix(r.Header.Get("Authorization"), "HMAC-SHA256 Credential=asset-ak/") {
			t.Fatalf("missing Volces authorization: %q", r.Header.Get("Authorization"))
		}
		var body map[string]any
		if err := json.NewDecoder(r.Body).Decode(&body); err != nil {
			t.Fatalf("decode body: %v", err)
		}
		raw, _ := json.Marshal(body)
		digest := sha256.Sum256(raw)
		if got := r.Header.Get("X-Content-Sha256"); got != hex.EncodeToString(digest[:]) {
			t.Fatalf("content hash mismatch got=%q", got)
		}
		switch r.URL.Query().Get("Action") {
		case "CreateAsset":
			if body["GroupId"] != "group-1" || body["AssetType"] != "Image" {
				t.Fatalf("unexpected CreateAsset body: %+v", body)
			}
			_ = json.NewEncoder(w).Encode(map[string]any{"ResponseMetadata": map[string]any{"RequestId": "create-rid"}, "Result": map[string]any{"Id": "asset-1"}})
		case "GetAsset":
			_ = json.NewEncoder(w).Encode(map[string]any{"ResponseMetadata": map[string]any{"RequestId": "get-rid"}, "Result": map[string]any{"Id": "asset-1", "Status": "Active", "AssetType": "Image"}})
		default:
			t.Fatalf("unexpected Action: %q", r.URL.Query().Get("Action"))
		}
	}))
	defer server.Close()

	client := VolcesAssetClient{HTTPClient: server.Client(), Now: func() time.Time {
		return time.Date(2026, 7, 18, 1, 2, 3, 0, time.UTC)
	}}
	credentials := VolcesAssetCredentials{AccessKey: "asset-ak", SecretKey: "asset-sk", Endpoint: server.URL}
	created, requestID, err := client.CreateAsset(context.Background(), credentials, map[string]any{"GroupId": "group-1", "URL": "https://example.com/person.png", "AssetType": "Image", "ProjectName": "default"})
	if err != nil || created.ID != "asset-1" || requestID != "create-rid" {
		t.Fatalf("unexpected CreateAsset result=%+v requestID=%s err=%v", created, requestID, err)
	}
	asset, requestID, err := client.GetAsset(context.Background(), credentials, map[string]any{"Id": "asset-1", "ProjectName": "default"})
	if err != nil || asset.Status != "Active" || requestID != "get-rid" {
		t.Fatalf("unexpected GetAsset result=%+v requestID=%s err=%v", asset, requestID, err)
	}
	if strings.Join(calls, ",") != "CreateAsset,GetAsset" {
		t.Fatalf("unexpected actions: %+v", calls)
	}
}
