package capability

import (
	"context"
	"encoding/json"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"

	"github.com/stretchr/testify/require"
)

func TestProjectionClientUpsertsAuthorityProjection(t *testing.T) {
	var requestPath string
	var requestAuth string
	var payload authorityProjectionRequest
	server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		requestPath = request.URL.Path
		requestAuth = request.Header.Get("Authorization")
		require.NoError(t, json.NewDecoder(request.Body).Decode(&payload))
		writer.WriteHeader(http.StatusOK)
	}))
	defer server.Close()

	projection := AuthorityProjection{
		OrganizationID:      "org_test",
		WorkspaceID:         "wsp_test",
		AgentID:             "agt_test",
		MemberID:            "mem_test",
		MachineID:           "mac_test",
		RuntimeSessionID:    "ars_test",
		AuthorityGeneration: 1,
		OrganizationStatus:  StatusActive,
		WorkspaceStatus:     StatusActive,
		AgentStatus:         StatusActive,
		RuntimeStatus:       StatusActive,
	}
	projection.ID = ProjectionID(projection)

	client := NewProjectionClient(server.URL, "internal-token", server.Client())
	err := client.UpsertAuthorityProjection(context.Background(), projection)
	require.NoError(t, err)

	require.Equal(t, "/internal/maas/v1/authority-projections/"+projection.ID, requestPath)
	require.Equal(t, "Bearer internal-token", requestAuth)
	require.Equal(t, "org_test", payload.OrganizationID)
	require.Equal(t, "mac_test", payload.MachineID)
	require.Equal(t, int64(1), payload.AuthorityGeneration)
	require.Equal(t, StatusActive, payload.RuntimeStatus)
}

func TestProjectionClientReportsFailedUpsertWithoutToken(t *testing.T) {
	server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, _ *http.Request) {
		http.Error(writer, "unauthorized", http.StatusUnauthorized)
	}))
	defer server.Close()

	client := NewProjectionClient(server.URL, "secret-token", server.Client())
	err := client.UpsertAuthorityProjection(context.Background(), AuthorityProjection{
		ID:                  "map_test",
		OrganizationID:      "org_test",
		WorkspaceID:         "wsp_test",
		AgentID:             "agt_test",
		MemberID:            "mem_test",
		MachineID:           "mac_test",
		RuntimeSessionID:    "ars_test",
		AuthorityGeneration: 1,
	})

	require.Error(t, err)
	require.Contains(t, err.Error(), "HTTP 401")
	require.NotContains(t, err.Error(), "secret-token")
	require.True(t, strings.Contains(err.Error(), "unauthorized"))
}
