104 lines
2.8 KiB
Go
104 lines
2.8 KiB
Go
package batch
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"sub2api-cn-relay-manager/internal/probe"
|
|
)
|
|
|
|
type ReuseInput struct {
|
|
ProviderMatched bool
|
|
ProviderID string
|
|
CanonicalModelFamilies []string
|
|
MatchedAccountID int64
|
|
MatchedAccountState MatchedAccountState
|
|
ExistingProviderID string
|
|
ExistingAccessStatus AccessStatus
|
|
ExistingCanonicalFamilys []string
|
|
}
|
|
|
|
type ReuseDecision struct {
|
|
ProvisionReused bool
|
|
ReusedFromProviderID string
|
|
ReusedFromAccountID int64
|
|
MatchedAccountState MatchedAccountState
|
|
AccountResolution AccountResolution
|
|
FamilyCovered bool
|
|
}
|
|
|
|
func DecideReuse(input ReuseInput) ReuseDecision {
|
|
decision := ReuseDecision{
|
|
MatchedAccountState: input.MatchedAccountState,
|
|
AccountResolution: AccountResolutionCreated,
|
|
FamilyCovered: canonicalFamiliesCovered(input.CanonicalModelFamilies, input.ExistingCanonicalFamilys),
|
|
}
|
|
|
|
if input.MatchedAccountState == "" {
|
|
decision.MatchedAccountState = MatchedAccountStateNone
|
|
}
|
|
|
|
if !providerMatched(input) || !decision.FamilyCovered {
|
|
return decision
|
|
}
|
|
|
|
if input.ExistingAccessStatus == AccessStatusBroken || input.MatchedAccountState == MatchedAccountStateBroken {
|
|
decision.AccountResolution = AccountResolutionReplaced
|
|
return decision
|
|
}
|
|
|
|
switch input.MatchedAccountState {
|
|
case MatchedAccountStateDisabled, MatchedAccountStateDeprecated:
|
|
decision.ProvisionReused = true
|
|
decision.ReusedFromProviderID = strings.TrimSpace(input.ExistingProviderID)
|
|
decision.ReusedFromAccountID = input.MatchedAccountID
|
|
decision.AccountResolution = AccountResolutionReactivated
|
|
return decision
|
|
case MatchedAccountStateActive, MatchedAccountStateNone, "":
|
|
decision.ProvisionReused = true
|
|
decision.ReusedFromProviderID = strings.TrimSpace(input.ExistingProviderID)
|
|
decision.ReusedFromAccountID = input.MatchedAccountID
|
|
decision.AccountResolution = AccountResolutionReused
|
|
return decision
|
|
default:
|
|
return decision
|
|
}
|
|
}
|
|
|
|
func canonicalFamiliesCovered(requested []string, existing []string) bool {
|
|
if len(requested) == 0 || len(existing) == 0 {
|
|
return false
|
|
}
|
|
|
|
existingSet := make(map[string]struct{}, len(existing))
|
|
for _, family := range existing {
|
|
canonical := probe.CanonicalModelFamily(family)
|
|
if canonical == "" {
|
|
continue
|
|
}
|
|
existingSet[canonical] = struct{}{}
|
|
}
|
|
|
|
for _, family := range requested {
|
|
canonical := probe.CanonicalModelFamily(family)
|
|
if canonical == "" {
|
|
return false
|
|
}
|
|
if _, ok := existingSet[canonical]; !ok {
|
|
return false
|
|
}
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func sameProvider(left, right string) bool {
|
|
return strings.TrimSpace(left) != "" && strings.TrimSpace(left) == strings.TrimSpace(right)
|
|
}
|
|
|
|
func providerMatched(input ReuseInput) bool {
|
|
if input.ProviderMatched {
|
|
return true
|
|
}
|
|
return sameProvider(input.ProviderID, input.ExistingProviderID)
|
|
}
|