package authorization

import (
	"github.com/aquasecurity/trivy/pkg/iac/providers/azure/authorization"
	"github.com/aquasecurity/trivy/pkg/iac/terraform"
)

func Adapt(modules terraform.Modules) authorization.Authorization {
	return authorization.Authorization{
		RoleDefinitions: adaptRoleDefinitions(modules),
		RoleAssignments: adaptRoleAssignments(modules),
	}
}

func adaptRoleDefinitions(modules terraform.Modules) []authorization.RoleDefinition {
	var roleDefinitions []authorization.RoleDefinition
	for _, module := range modules {
		for _, resource := range module.GetResourcesByType("azurerm_role_definition") {
			roleDefinitions = append(roleDefinitions, adaptRoleDefinition(resource))
		}
	}
	return roleDefinitions
}

func adaptRoleDefinition(resource *terraform.Block) authorization.RoleDefinition {
	permissionsBlocks := resource.GetBlocks("permissions")
	var permissionsVal []authorization.Permission

	for _, permissionsBlock := range permissionsBlocks {
		actionsAttr := permissionsBlock.GetAttribute("actions")
		permissionsVal = append(permissionsVal, authorization.Permission{
			Metadata: permissionsBlock.GetMetadata(),
			Actions:  actionsAttr.AsStringValues(),
		})
	}

	assignableScopesAttr := resource.GetAttribute("assignable_scopes")
	return authorization.RoleDefinition{
		Metadata:         resource.GetMetadata(),
		Permissions:      permissionsVal,
		AssignableScopes: assignableScopesAttr.AsStringValues(),
	}
}

func adaptRoleAssignments(modules terraform.Modules) []authorization.RoleAssignment {
	var roleAssignments []authorization.RoleAssignment
	for _, module := range modules {
		for _, resource := range module.GetResourcesByType("azurerm_role_assignment") {
			roleAssignments = append(roleAssignments, adaptRoleAssignment(resource))
		}
	}
	return roleAssignments
}

func adaptRoleAssignment(resource *terraform.Block) authorization.RoleAssignment {
	roleDefIdAttr := resource.GetAttribute("role_definition_id")
	roleDefNameAttr := resource.GetAttribute("role_definition_name")
	principalIdAttr := resource.GetAttribute("principal_id")
	principalTypeAttr := resource.GetAttribute("principal_type")

	return authorization.RoleAssignment{
		Metadata:           resource.GetMetadata(),
		RoleDefinitionId:   roleDefIdAttr.AsStringValueOrDefault("", resource),
		RoleDefinitionName: roleDefNameAttr.AsStringValueOrDefault("", resource),
		PrincipalId:        principalIdAttr.AsStringValueOrDefault("", resource),
		PrincipalType:      principalTypeAttr.AsStringValueOrDefault("", resource),
	}
}
