# This policy requires `aws_cloudwatch_event_bus` resources to be attached to a policy.

# Copyright IBM Corp. 2025, 2026
# SPDX-License-Identifier: BUSL-1.1

# Imports

import "tfplan/v2" as tfplan
import "tfresources" as tf
import "report" as report
import "collection" as collection
import "collection/maps" as maps
import "strings"

# Constants

const = {
	"policy_name": "eventbridge-custom-event-bus-should-have-attached-policy",
	"message":     "Policy should be attached for 'aws_cloudwatch_event_bus' resource. Refer to https://docs.aws.amazon.com/securityhub/latest/userguide/eventbridge-controls.html#eventbridge-3 for more details.",
	"resource_aws_cloudwatch_event_bus_policy": "aws_cloudwatch_event_bus_policy",
	"resource_aws_cloudwatch_event_bus":        "aws_cloudwatch_event_bus",
	"event_bus_name":                           "event_bus_name",
	"name":                                     "name",
}

# Functions

get_bus_name_complaint = func(resources) {
	return collection.reject(resources, func(res) {
		bus_name_values = maps.get(res, "values." + const.event_bus_name, {})
		if bus_name_values is empty {
			return true
		}
		return false
	})
}

# Variables

plan_resources = tf.plan(tfplan.planned_values.resources)
event_bus_policy_resources = plan_resources.type(const.resource_aws_cloudwatch_event_bus_policy).resources
event_bus_resources = plan_resources.type(const.resource_aws_cloudwatch_event_bus).resources

event_bus_complaint = get_bus_name_complaint(event_bus_policy_resources)
if event_bus_complaint is not defined {
	violations = []
}

event_bus_addresses = map event_bus_complaint as _, res {
	maps.get(res, "values." + const.event_bus_name, {})
}

violations = filter event_bus_resources as _, res {
	maps.get(res, "values." + const.name, {}) not in event_bus_addresses
}

summary = {
	"policy_name": const.policy_name,
	"violations": map violations as _, v {
		{
			"address":        v.address,
			"module_address": v.module_address,
			"message":        const.message,
		}
	},
}

# Outputs

print(report.generate_policy_report(summary))

# Rules

main = rule {
	violations is empty
}
