package awsauth

import "reflect"

var (
	DefaultRetryerBackoffFactor float64 = 2.0
	DefaultRetryerBackoffJitter         = true
	UpdateUsernameDefaultValue  bool    = true
)

// AwsAuthData represents the data of the aws-auth configmap
type AwsAuthData struct {
	MapRoles []*RolesAuthMap `yaml:"mapRoles"`
	MapUsers []*UsersAuthMap `yaml:"mapUsers"`
}

// SetMapRoles sets the MapRoles element
func (m *AwsAuthData) SetMapRoles(authMap []*RolesAuthMap) {
	m.MapRoles = authMap
}

func (m *AwsAuthData) AppendMapRoles(authMap *RolesAuthMap) {
	m.MapRoles = append(m.MapRoles, authMap)
}

func (m *AwsAuthData) AppendMapRolesIfNotExists(authMap *RolesAuthMap) {
	if !m.ContainsMapRole(*authMap) {
		m.MapRoles = append(m.MapRoles, authMap)
	}
}

func (m *AwsAuthData) DeleteMapRoles(authMap RolesAuthMap) {
	for i, role := range m.MapRoles {
		if reflect.DeepEqual(*role, authMap) {
			m.MapRoles = append(m.MapRoles[:i], m.MapRoles[i+1:]...)
		}
	}
}

func (m *AwsAuthData) ContainsMapRole(roleMap RolesAuthMap) bool {
	for _, role := range m.MapRoles {
		if reflect.DeepEqual(*role, roleMap) {
			return true
		}
	}
	return false
}

// SetMapUsers sets the MapUsers element
func (m *AwsAuthData) SetMapUsers(authMap []*UsersAuthMap) {
	m.MapUsers = authMap
}

func (m *AwsAuthData) AppendMapUsersIfNotExist(authMap *UsersAuthMap) {
	for _, user := range m.MapUsers {
		if reflect.DeepEqual(*user, *authMap) {
			return
		}
		m.MapUsers = append(m.MapUsers, authMap)
	}
}

func (m *AwsAuthData) MergeAuthData(overlay *AwsAuthData) {
	for _, role := range overlay.MapRoles {
		m.AppendMapRolesIfNotExists(role)
	}
	for _, user := range overlay.MapUsers {
		m.AppendMapUsersIfNotExist(user)
	}
}

// RolesAuthMap is the basic structure of a mapRoles authentication object
type RolesAuthMap struct {
	RoleARN  string   `yaml:"rolearn"`
	Username string   `yaml:"username"`
	Groups   []string `yaml:"groups,omitempty"`
}

// UsersAuthMap is the basic structure of a mapUsers authentication object
type UsersAuthMap struct {
	UserARN  string   `yaml:"userarn"`
	Username string   `yaml:"username"`
	Groups   []string `yaml:"groups,omitempty"`
}

// NewRolesAuthMap returns a new NewRolesAuthMap
func NewRolesAuthMap(rolearn, username string, groups []string) *RolesAuthMap {
	return &RolesAuthMap{
		RoleARN:  rolearn,
		Username: username,
		Groups:   groups,
	}
}

// NewUsersAuthMap returns a new NewUsersAuthMap
func NewUsersAuthMap(userarn, username string, groups []string) *UsersAuthMap {
	return &UsersAuthMap{
		UserARN:  userarn,
		Username: username,
		Groups:   groups,
	}
}
