package connprofile

import (
	"context"
	"fmt"
	"time"

	"github.com/pingcap/errcode"
	"github.com/pingcap/errors"
	"github.com/tidbcloud/core-svc/idl/pbgen/proto/core"
	"github.com/tidbcloud/dataflow-service/internal/db"
	"github.com/tidbcloud/dataflow-service/internal/db/entity"
	"github.com/tidbcloud/dataflow-service/internal/model/base"
	"github.com/tidbcloud/dataflow-service/pkg/account/accountdb"
	"github.com/tidbcloud/eks-provider/api/v1alpha1"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

const (
	failedPLEndpointVisibleTime      = 5 * time.Minute
	maxMatchCountForUnusedPLEndpoint = 30
	// staleNonAvailablePLEndpointAge non-available pl-endpoints older than this will be checked for cleanup.
	staleNonAvailablePLEndpointAge = 24 * time.Hour
)

type Model struct {
	base.Model
}

func (m Model) UserContext(ctx context.Context, user *accountdb.User) UserContext {
	return UserContext{
		Model:       m,
		UserContext: m.BaseUserContext(ctx, user, "conn profile"),
	}
}

func (m Model) RunDeduplicatePLEndpoints(ctx context.Context) error {
	logger := m.Log().With(zap.String("action", "deduplicate"))
	logger.Info("deduplicate pl endpoints worker running")
	plEndpoints, err := getPLEndpointByPhases(entity.PLEndpointPhaseNew)
	if err != nil {
		logger.Error("failed to query pl endpoints", zap.Error(err))
		return err
	}
	for _, plEndpoint := range plEndpoints {
		m.deduplicatePLEndpoint(ctx, logger, &plEndpoint)
	}
	return nil
}

func (m Model) deduplicatePLEndpoint(ctx context.Context, inputLogger *zap.Logger, plEndpoint *entity.DFPrivateLinkEndpoint) {
	logger := inputLogger.With(zap.Uint64("pl-endpoint-id", uint64(plEndpoint.ID)))
	// there might be multiple pl-endpoint created in metadb with same (network, service-name),
	// see create pl-endpoint api description. we deduplicate them here to avoid create multiple private link endpoints
	// in same network
	workingPLEndpoint, err := getWorkingPLEndpoint(plEndpoint.NetworkNS, plEndpoint.NetworkName, plEndpoint.ServiceName)
	if err != nil && errors.Cause(err) != gorm.ErrRecordNotFound {
		logger.Error("failed to get pl-endpoint in creating", zap.Error(err))
		return
	}
	if workingPLEndpoint != nil {
		msg := "Another private link with same service name is in-creating, please try again."
		if err = markPLEndpointFailed(plEndpoint, msg); err != nil {
			logger.Error("failed to mark private link as failed", zap.Error(err))
		} else {
			logger.Info("pl-endpoint is duplicated, into failed phase")
		}
		return
	}

	plEndpoint.Phase = entity.PLEndpointPhasePending
	if err = updatePLEndpoint(plEndpoint, entity.DFPrivateLinkEndpointDBSchema.Phase); err != nil {
		logger.Error("failed to update pl-endpoint")
	} else {
		logger.Info("pl-endpoint into pending phase")
	}
}

func (m Model) RunCreatePLEndpoints(ctx context.Context) error {
	logger := m.Log().With(zap.String("action", "create"))
	logger.Info("create pl-endpoint worker running")
	plEndpoints, err := getPLEndpointByPhases(entity.PLEndpointPhasePending, entity.PLEndpointPhasePendingAcceptance)
	if err != nil {
		logger.Error("failed to query pending pl endpoints", zap.Error(err))
		return err
	}
	for _, plEndpoint := range plEndpoints {
		m.createPLEndpoint(ctx, logger, &plEndpoint)
	}
	return nil
}

func (m Model) createPLEndpoint(ctx context.Context, inputLogger *zap.Logger, plEndpoint *entity.DFPrivateLinkEndpoint) {
	logger := inputLogger.With(zap.Uint64("pl-endpoint-id", uint64(plEndpoint.ID)))
	resourceAPI, err := GetResourceAPI(ctx, plEndpoint.TenantID.Uint64(), plEndpoint.Provider,
		plEndpoint.Region, plEndpoint.IsRegional)
	if err != nil {
		logger.Error("failed to get resource api", zap.Error(err))
		return
	}
	plEndpointCR, err := resourceAPI.GetPLEndpoint(ctx, plEndpoint.NetworkNS, plEndpoint.ID)
	if err != nil && !resourceAPI.IsNotFound(err) {
		logger.Error("failed to get private link cr", zap.Error(err))
		return
	}
	if plEndpointCR == nil {
		logger.Info("create pl endpoint CR")
		err = resourceAPI.CreatePLEndpointIgnoreExists(ctx, plEndpoint.ID, plEndpoint.Provider, plEndpoint.Region,
			plEndpoint.NetworkNS, plEndpoint.NetworkName, plEndpoint.ServiceName,
			plEndpoint.TenantID.Uint64(), plEndpoint.ProjectID.Uint64())
		if err != nil {
			logger.Error("create private link CR failed", zap.Error(err))
		}
		return
	}
	crStatus := plEndpointCR.Status
	logger.Info("private link CR status", zap.Reflect("status", crStatus))
	switch crStatus.Phase {
	case v1alpha1.PrivateLinkEndpointPhaseError:
		if err = markPLEndpointFailed(plEndpoint, crStatus.ErrorMessage); err != nil {
			logger.Error("failed to mark private link as failed", zap.Error(err))
		} else {
			logger.Info("pl-endpoint into failed phase")
		}
		return
	case v1alpha1.PrivateLinkEndpointPhaseDeleting:
		// should not happen
		logger.Error("invalid private link phase", zap.Reflect("phase", crStatus.Phase))
		return
	}
	if crStatus.AtProvider.State == nil {
		logger.Info("provider state of pl endpoint CR is empty")
		return
	}

	var endpointID string
	if crStatus.AtProvider.EndpointID != nil {
		endpointID = *crStatus.AtProvider.EndpointID
	}
	shouldUpdateEndpointID := len(plEndpoint.EndpointID) == 0 && len(endpointID) > 0
	endpointState := *crStatus.AtProvider.State
	// endpoint state description: https://docs.aws.amazon.com/vpc/latest/privatelink/concepts.html
	// note: aws's description is not correct, if the endpoint request need service provider accept, it'll be
	// in PendingAcceptance state which mismatch its description: "This is the initial state if requests are manually accepted."
	logger.Info("current provider state of pl endpoint", zap.Reflect("provider-state", endpointState))
	switch endpointState {
	case v1alpha1.EndpointResourceStatePending:
		if plEndpoint.Phase == entity.PLEndpointPhasePendingAcceptance || shouldUpdateEndpointID {
			// when user has clicked "Accept", it will go into pending again
			plEndpoint.Phase = entity.PLEndpointPhasePending
			plEndpoint.EndpointID = endpointID
			if err = updatePLEndpoint(plEndpoint, entity.DFPrivateLinkEndpointDBSchema.Phase,
				entity.DFPrivateLinkEndpointDBSchema.EndpointID); err != nil {
				logger.Error("failed to update private link", zap.Error(err))
			} else {
				logger.Info("pl-endpoint into pending phase again(from pending-acceptance)")
			}
		}
		return
	case v1alpha1.EndpointResourceStatePendingAcceptance:
		if plEndpoint.Phase == entity.PLEndpointPhasePending || shouldUpdateEndpointID {
			plEndpoint.Phase = entity.PLEndpointPhasePendingAcceptance
			plEndpoint.EndpointID = endpointID
			if err = updatePLEndpoint(plEndpoint, entity.DFPrivateLinkEndpointDBSchema.Phase,
				entity.DFPrivateLinkEndpointDBSchema.EndpointID); err != nil {
				logger.Error("failed to update private link", zap.Error(err))
			} else {
				logger.Info("pl-endpoint into pending-acceptance phase")
			}
		}
		return
	case v1alpha1.EndpointResourceStateRejected,
		v1alpha1.EndpointResourceStateExpired,
		v1alpha1.EndpointResourceStateFailed:
		errMsg := fmt.Sprintf("State of private link is: %s, please try again.", endpointState)
		if err = markPLEndpointFailed(plEndpoint, errMsg); err != nil {
			logger.Error("failed to mark private link as failed", zap.Error(err))
		} else {
			logger.Info("pl-endpoint into failed phase")
		}
		return
	case v1alpha1.EndpointResourceStateDeleted,
		v1alpha1.EndpointResourceStateDeleting:
		// should not happen
		logger.Error("invalid provider state of private link", zap.Reflect("state", endpointState))
		return
	case v1alpha1.EndpointResourceStateAvailable:
		if len(crStatus.AtProvider.DNSEntries) == 0 {
			// should not happen
			logger.Error("empty dns entries when provider state is available")
			return
		}
	}

	dnsEntries := crStatus.AtProvider.DNSEntries

	logger.Info("got private link endpoint dns", zap.Reflect("dns", dnsEntries))
	regionalDNS, zonalDNSMap := m.decodePLEndpointDNS(dnsEntries)
	if len(regionalDNS) == 0 {
		// should not happen
		logger.Error("regional dns is empty")
		return
	}
	plEndpoint.Phase = entity.PLEndpointPhaseAvailable
	plEndpoint.EndpointID = endpointID
	plEndpoint.RegionalDNS = regionalDNS
	plEndpoint.ZonalDNS = &entity.ZonalDNS{DNS: zonalDNSMap}
	err = updatePLEndpoint(plEndpoint, entity.DFPrivateLinkEndpointDBSchema.Phase,
		entity.DFPrivateLinkEndpointDBSchema.EndpointID,
		entity.DFPrivateLinkEndpointDBSchema.RegionalDNS,
		entity.DFPrivateLinkEndpointDBSchema.ZonalDNS)
	if err != nil {
		logger.Error("update private link failed", zap.Error(err))
	} else {
		logger.Info("pl-endpoint into available phase")
	}
}

func (m Model) decodePLEndpointDNS(entries []v1alpha1.DNSEntry) (string, map[string]string) {
	var regionalDNS string
	zonalDNSMap := make(map[string]string)
	for _, entry := range entries {
		if entry.Zone == nil {
			regionalDNS = *entry.DNSName
		} else {
			zonalDNSMap[*entry.Zone] = *entry.DNSName
		}
	}
	return regionalDNS, zonalDNSMap
}

// RunDeleteFailedPLEndpoints delete failed pl endpoints.
// we need to return the status to user if it's failed, so need to keep it in metadb as failed for a while,
// after enough time, we delete it logically to release resources.
func (m Model) RunDeleteFailedPLEndpoints(ctx context.Context) error {
	logger := m.Log().With(zap.String("action", "delete-failed"))
	logger.Info("delete failed pl-endpoints worker running")
	plEndpoints, err := getFailedPLEndpoint2Delete()
	if err != nil {
		logger.Error("failed to query failed pl endpoints", zap.Error(err))
		return err
	}
	for _, plEndpoint := range plEndpoints {
		m.deleteFailedPLEndpoint(ctx, logger, &plEndpoint)
	}
	return nil
}

func (m Model) deleteFailedPLEndpoint(ctx context.Context, inputLogger *zap.Logger, plEndpoint *entity.DFPrivateLinkEndpoint) {
	logger := inputLogger.With(zap.Uint64("pl-endpoint-id", uint64(plEndpoint.ID)))
	resourceAPI, err := GetResourceAPI(ctx, plEndpoint.TenantID.Uint64(), plEndpoint.Provider,
		plEndpoint.Region, plEndpoint.IsRegional)
	if err != nil {
		logger.Error("failed to get resource api", zap.Error(err))
		return
	}
	plEndpointCR, err := resourceAPI.GetPLEndpoint(ctx, plEndpoint.NetworkNS, plEndpoint.ID)
	if err != nil && !resourceAPI.IsNotFound(err) {
		logger.Error("failed to get private link cr", zap.Error(err))
		return
	}
	if plEndpointCR != nil {
		logger.Info("delete pl endpoint cr")
		if err = resourceAPI.DeletePLEndpointIgnoreNotFound(ctx, plEndpoint.NetworkNS, plEndpoint.ID); err != nil {
			logger.Error("failed to delete private link cr", zap.Error(err))
			return
		}
	}
	now := time.Now()
	plEndpoint.Phase = entity.PLEndpointPhaseDeleted
	plEndpoint.DeletedAt = &now
	err = updatePLEndpoint(plEndpoint, entity.DFPrivateLinkEndpointDBSchema.Phase,
		entity.DFPrivateLinkEndpointDBSchema.DeletedAt)
	if err != nil {
		logger.Error("update private link failed", zap.Error(err))
	} else {
		logger.Info("pl-endpoint into deleted phase")
	}
}

// RunClearUnusedPLEndpoints mark unused pl-endpoint as failed if it's matched for a few times.
// For available pl-endpoints: check immediately with 30-minute threshold.
// For non-available pl-endpoints (new, pending, pending-acceptance): only check if created more than 1 day ago.
// pl-endpoint in failed phase will be deleted by RunDeleteFailedPLEndpoints.
// see PrivateLinkEndpointWorker.unusedEndpointMatchCount for more detail.
func (m Model) RunClearUnusedPLEndpoints(ctx context.Context, matchCountMap map[string]int) error {
	logger := m.Log().With(zap.String("action", "clear-unused-pl-endpoint"))
	logger.Info("worker running")

	// Check available pl-endpoints
	availablePLEndpoints, err := getAllAvailablePLEndpoints()
	if err != nil {
		logger.Error("failed to get available pl-endpoints", zap.Error(err))
		return err
	}

	// Check stale non-available pl-endpoints (created more than 1 day ago)
	staleNonAvailablePLEndpoints, err := getStaleNonAvailablePLEndpoints()
	if err != nil {
		logger.Error("failed to get stale non-available pl-endpoints", zap.Error(err))
		return err
	}

	// Combine and process all pl-endpoints
	allPLEndpoints := append(availablePLEndpoints, staleNonAvailablePLEndpoints...)
	for _, plEndpoint := range allPLEndpoints {
		isUsing, err := CheckIsPLEndpointBeingUsed(&plEndpoint, logger)
		innerLogger := logger.With(zap.Uint64("project", plEndpoint.ProjectID.Uint64()), zap.String("region", plEndpoint.Region),
			zap.String("service-name", plEndpoint.ServiceName), zap.String("phase", string(plEndpoint.Phase)))
		if err != nil {
			innerLogger.Error("failed to check is using for pl-endpoint", zap.Error(err))
			continue
		}
		key := fmt.Sprintf("%d/%s/%s", plEndpoint.ProjectID, plEndpoint.Region, plEndpoint.ServiceName)
		if isUsing {
			// there's still job using this pl-endpoint, reset counter
			delete(matchCountMap, key)
			continue
		}
		matchCountMap[key]++
		innerLogger.Info("pl-endpoint is matched", zap.Int("times", matchCountMap[key]))
		if matchCountMap[key] < maxMatchCountForUnusedPLEndpoint {
			continue
		}
		if err = markPLEndpointFailed(&plEndpoint, "Unused for too long, deleted automatically."); err != nil {
			innerLogger.Error("failed to mark private link as failed", zap.Error(err))
		} else {
			// delete from the map after mark it as failed successfully.
			delete(matchCountMap, key)
			innerLogger.Info("mark pl-endpoint as failed phase due to inactive")
		}
	}
	return nil
}

func NewModel(log *zap.Logger) Model {
	return Model{
		Model: base.NewModel(log),
	}
}

type UserContext struct {
	Model
	base.UserContext
}

func (c UserContext) Create(profile *entity.DFConnProfile) (uint64, error) {
	if err := db.Transaction(func(tx *gorm.DB) error {
		return profile.Create(tx)
	}); err != nil {
		return 0, errors.Trace(err)
	}
	return uint64(profile.ID), nil
}

func (c UserContext) CreatePLEndpoint(cluster *core.Cluster, serviceName string) (uint64, error) {
	plEndpoint := &entity.DFPrivateLinkEndpoint{
		CreatorUID:  entity.ID(c.UserID()),
		TenantID:    entity.ID(cluster.TenantId),
		ProjectID:   entity.ID(cluster.ProjectId),
		Provider:    cluster.InfraProviderType,
		Region:      cluster.RegionName,
		NetworkNS:   cluster.GetDataPlaneInfo().GetK8SNamespace(),
		NetworkName: cluster.GetDataPlaneInfo().GetNetworkName(),
		ServiceName: serviceName,
		Phase:       entity.PLEndpointPhaseNew,
		IsRegional:  true,
	}
	if err := db.Transaction(func(tx *gorm.DB) error {
		return plEndpoint.Create(tx)
	}); err != nil {
		return 0, errors.Trace(err)
	}
	return uint64(plEndpoint.ID), nil
}

func GetNonFailedNonDeletedPLEndpoint(networkNS, networkName, serviceName string) (*entity.DFPrivateLinkEndpoint, error) {
	var res entity.DFPrivateLinkEndpoint
	if err := db.Transaction(func(tx *gorm.DB) error {
		return entity.NewDFPrivateLinkEndpointQuerySet(tx).
			NetworkNSEq(networkNS).NetworkNameEq(networkName).ServiceNameEq(serviceName).
			PhaseNotIn(entity.PLEndpointPhaseFailed, entity.PLEndpointPhaseDeleted).One(&res)
	}); err != nil {
		return nil, errors.Trace(err)
	}
	return &res, nil
}

func GetAvailablePrivateLink(networkNS, networkName, serviceName string) (*entity.DFPrivateLinkEndpoint, error) {
	var res entity.DFPrivateLinkEndpoint
	if err := db.Transaction(func(tx *gorm.DB) error {
		return entity.NewDFPrivateLinkEndpointQuerySet(tx).
			NetworkNSEq(networkNS).NetworkNameEq(networkName).
			ServiceNameEq(serviceName).PhaseEq(entity.PLEndpointPhaseAvailable).One(&res)
	}); err != nil {
		return nil, errors.Trace(err)
	}
	return &res, nil
}

func getAllAvailablePLEndpoints() ([]entity.DFPrivateLinkEndpoint, error) {
	var res []entity.DFPrivateLinkEndpoint
	if err := db.Transaction(func(tx *gorm.DB) error {
		return entity.NewDFPrivateLinkEndpointQuerySet(tx).PhaseEq(entity.PLEndpointPhaseAvailable).All(&res)
	}); err != nil {
		return nil, errors.Trace(err)
	}
	return res, nil
}

// getStaleNonAvailablePLEndpoints returns non-available pl-endpoints created more than 1 day ago.
func getStaleNonAvailablePLEndpoints() ([]entity.DFPrivateLinkEndpoint, error) {
	var res []entity.DFPrivateLinkEndpoint
	if err := db.Transaction(func(tx *gorm.DB) error {
		staleTime := time.Now().Add(-staleNonAvailablePLEndpointAge)
		return entity.NewDFPrivateLinkEndpointQuerySet(tx).
			PhaseIn(entity.PLEndpointPhaseNew, entity.PLEndpointPhasePending, entity.PLEndpointPhasePendingAcceptance).
			CreatedAtLt(staleTime).
			All(&res)
	}); err != nil {
		return nil, errors.Trace(err)
	}
	return res, nil
}

func CheckIsPLEndpointBeingUsed(plEndpoint *entity.DFPrivateLinkEndpoint, logger *zap.Logger) (bool, error) {
	count, err := countRunningDMJobsForPLEndpoint(plEndpoint)
	if err != nil {
		logger.Error("failed to count running dm jobs for pl-endpoint", zap.Error(err))
		return false, err
	}
	if count > 0 {
		return true, nil
	}
	count, err = countRunningImportJobsForPLEndpoint(plEndpoint)
	if err != nil {
		logger.Error("failed to count running import jobs for pl-endpoint", zap.Error(err))
		return false, err
	}
	if count > 0 {
		return true, nil
	}
	return false, nil
}

func countRunningDMJobsForPLEndpoint(plEndpoint *entity.DFPrivateLinkEndpoint) (int64, error) {
	var count int64
	err := db.Transaction(func(tx *gorm.DB) error {
		return tx.Table("df_jobs a").
			Joins("join dm_job_sources b on a.id=b.job_id").
			Joins("join df_conn_profiles c on b.conn_profile_id=c.id").
			Where("a.phase in ('creating', 'created') and a.project_id=? and a.region=? and a.provider=? and c.endpoint_service_name =?",
				plEndpoint.ProjectID, plEndpoint.Region, plEndpoint.Provider, plEndpoint.ServiceName).
			Count(&count).Error
	})
	if err != nil {
		return 0, err
	}
	return count, nil
}

func countRunningImportJobsForPLEndpoint(plEndpoint *entity.DFPrivateLinkEndpoint) (int64, error) {
	var count int64
	err := db.Transaction(func(tx *gorm.DB) error {
		return tx.Table("imports").
			Where("status in ('preparing', 'importing', 'canceling') and project_id=? and region=? and provider=? and endpoint_service_name=?",
				plEndpoint.ProjectID, plEndpoint.Region, plEndpoint.Provider, plEndpoint.ServiceName).
			Where("conn_method = 'private-link'").
			Count(&count).Error
	})
	if err != nil {
		return 0, err
	}
	return count, nil
}

// get working pl-endpoint: in pending or pending-acceptance or available phase
// tried to merge with prev method, ugly too, so leave it.
func getWorkingPLEndpoint(networkNS, networkName, serviceName string) (*entity.DFPrivateLinkEndpoint, error) {
	var res entity.DFPrivateLinkEndpoint
	if err := db.Transaction(func(tx *gorm.DB) error {
		return entity.NewDFPrivateLinkEndpointQuerySet(tx).
			NetworkNSEq(networkNS).NetworkNameEq(networkName).ServiceNameEq(serviceName).
			PhaseIn(entity.PLEndpointPhasePending, entity.PLEndpointPhasePendingAcceptance, entity.PLEndpointPhaseAvailable).
			One(&res)
	}); err != nil {
		return nil, errors.Trace(err)
	}
	return &res, nil
}

func getPLEndpointByPhases(phases ...entity.PLEndpointPhase) ([]entity.DFPrivateLinkEndpoint, error) {
	var res []entity.DFPrivateLinkEndpoint
	if err := db.Transaction(func(tx *gorm.DB) error {
		return entity.NewDFPrivateLinkEndpointQuerySet(tx).PhaseIn(phases...).All(&res)
	}); err != nil {
		return nil, errors.Trace(err)
	}
	return res, nil
}

func getFailedPLEndpoint2Delete() ([]entity.DFPrivateLinkEndpoint, error) {
	var res []entity.DFPrivateLinkEndpoint
	if err := db.Transaction(func(tx *gorm.DB) error {
		tx = tx.Where("TIMESTAMPDIFF(SECOND, updated_at, UTC_TIMESTAMP()) > ?", int64(failedPLEndpointVisibleTime.Seconds()))
		return entity.NewDFPrivateLinkEndpointQuerySet(tx).PhaseEq(entity.PLEndpointPhaseFailed).All(&res)
	}); err != nil {
		return nil, errors.Trace(err)
	}
	return res, nil
}

func markPLEndpointFailed(plEndpoint *entity.DFPrivateLinkEndpoint, errMsg string) error {
	plEndpoint.Phase = entity.PLEndpointPhaseFailed
	plEndpoint.ErrMsg = errMsg
	return updatePLEndpoint(plEndpoint, entity.DFPrivateLinkEndpointDBSchema.Phase,
		entity.DFPrivateLinkEndpointDBSchema.ErrMsg)
}

func updatePLEndpoint(plEndpoint *entity.DFPrivateLinkEndpoint, fields ...entity.DFPrivateLinkEndpointDBSchemaField) error {
	return db.Transaction(func(tx *gorm.DB) error {
		return plEndpoint.Update(tx, fields...)
	})
}

func GetPLEndpointByID(id entity.ID) (*entity.DFPrivateLinkEndpoint, error) {
	var res entity.DFPrivateLinkEndpoint
	if err := db.Transaction(func(tx *gorm.DB) error {
		return entity.NewDFPrivateLinkEndpointQuerySet(tx).IDEq(id).One(&res)
	}); err != nil {
		return nil, errors.Trace(err)
	}
	return &res, nil
}

func GetConnProfileByIDs(profileIDs ...entity.ID) ([]entity.DFConnProfile, error) {
	var res []entity.DFConnProfile
	if err := db.Transaction(func(tx *gorm.DB) error {
		return entity.NewDFConnProfileQuerySet(tx).IDIn(profileIDs...).All(&res)
	}); err != nil {
		return nil, errors.Trace(err)
	}
	return res, nil
}

func MustGetConnProfileByID(profileID entity.ID) (*entity.DFConnProfile, error) {
	connProfiles, err := GetConnProfileByIDs(profileID)
	if err != nil {
		return nil, err
	}
	if len(connProfiles) == 0 {
		return nil, errcode.NewNotFoundErr(errors.Errorf("No such connection profile: %d", profileID))
	}
	return &connProfiles[0], nil
}
