package api

import (
	"context"
	"fmt"

	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v18/internal/api"
	"gitlab.com/gitlab-org/cluster-integration/gitlab-agent/v18/internal/gitlab"
)

const (
	AgentkInfoAPIPath = "/api/v4/internal/agents/agentk/agent_info"
	AgentwInfoAPIPath = "/api/v4/internal/agents/agentw/agent_info"
)

func GetAgentInfo(ctx context.Context, client gitlab.ClientInterface, agentTokenWithType api.AgentTokenWithType, opts ...gitlab.DoOption) (api.AgentInfo, error) {
	switch agentTokenWithType.Type { //nolint:exhaustive
	case api.AgentTypeKubernetes:
		return getAgentkInfo(ctx, client, agentTokenWithType, opts...)
	case api.AgentTypeWorkspace:
		return getAgentwInfo(ctx, client, agentTokenWithType, opts...)
	default:
		return nil, fmt.Errorf("unknown agent token type while fetching agent info: %v", agentTokenWithType.Type)
	}
}

func getAgentkInfo(ctx context.Context, client gitlab.ClientInterface, agentTokenWithType api.AgentTokenWithType, opts ...gitlab.DoOption) (*api.AgentkInfo, error) {
	response := &GetAgentkInfoResponse{}
	err := client.Do(ctx,
		joinOpts(opts,
			gitlab.WithPath(AgentkInfoAPIPath),
			gitlab.WithAgentTokenAndType(agentTokenWithType),
			gitlab.WithJWT(true),
			gitlab.WithResponseHandler(gitlab.ProtoJSONResponseHandler(response)),
		)...,
	)
	if err != nil {
		return nil, err
	}
	return response.ToAPIAgentInfo(), nil
}

func getAgentwInfo(ctx context.Context, client gitlab.ClientInterface, agentTokenWithType api.AgentTokenWithType, opts ...gitlab.DoOption) (*api.AgentwInfo, error) {
	response := &GetAgentwInfoResponse{}
	err := client.Do(ctx,
		joinOpts(opts,
			gitlab.WithPath(AgentwInfoAPIPath),
			gitlab.WithAgentTokenAndType(agentTokenWithType),
			gitlab.WithJWT(true),
			gitlab.WithResponseHandler(gitlab.ProtoJSONResponseHandler(response)),
		)...,
	)
	if err != nil {
		return nil, err
	}
	return response.ToAPIAgentInfo(), nil
}
