package compute

import (
	"testing"

	"github.com/aquasecurity/trivy/internal/testutil"
	"github.com/aquasecurity/trivy/pkg/iac/adapters/common"
	"github.com/aquasecurity/trivy/pkg/iac/adapters/terraform/tftestutil"
	"github.com/aquasecurity/trivy/pkg/iac/providers/google/compute"
	iacTypes "github.com/aquasecurity/trivy/pkg/iac/types"
)

func Test_adaptNetworks(t *testing.T) {
	tests := []struct {
		name      string
		terraform string
		expected  []compute.Network
	}{
		{
			name: "defined",
			terraform: `
			resource "google_compute_subnetwork" "example" {
				name          = "test-subnetwork"
				network       = google_compute_network.example.id
				log_config {
				  aggregation_interval = "INTERVAL_10_MIN"
				  flow_sampling        = 0.5
				  metadata             = "INCLUDE_ALL_METADATA"
				}
			  }

			  resource "google_compute_network" "example" {
				name                    = "test-network"
				auto_create_subnetworks = false
			  }

			  resource "google_compute_firewall" "example" {
				name        = "my-firewall-rule"
				network = google_compute_network.example.name
				source_ranges = ["1.2.3.4/32"]
				allow {
				  protocol = "icmp"
				  ports     = ["80", "8080", "9090-9095"]
				}
			  }
`,
			expected: []compute.Network{
				{
					Firewall: &compute.Firewall{
						Name: iacTypes.StringTest("my-firewall-rule"),
						IngressRules: []compute.IngressRule{
							{
								FirewallRule: compute.FirewallRule{
									IsAllow:  iacTypes.BoolTest(true),
									Protocol: iacTypes.StringTest("icmp"),
									Enforced: iacTypes.BoolTest(true),
									Ports: []common.PortRange{
										{
											Start: iacTypes.IntTest(80),
											End:   iacTypes.IntTest(80),
										},
										{
											Start: iacTypes.IntTest(8080),
											End:   iacTypes.IntTest(8080),
										},
										{
											Start: iacTypes.IntTest(9090),
											End:   iacTypes.IntTest(9095),
										},
									},
								},
								SourceRanges: []iacTypes.StringValue{
									iacTypes.StringTest("1.2.3.4/32"),
								},
							},
						},
					},
					Subnetworks: []compute.SubNetwork{
						{
							Name:           iacTypes.StringTest("test-subnetwork"),
							EnableFlowLogs: iacTypes.BoolTest(true),
							Purpose:        iacTypes.StringTest("PRIVATE_RFC_1918"),
						},
					},
				},
			},
		},
		{
			name: "defaults",
			terraform: `
			resource "google_compute_subnetwork" "example" {
				network = google_compute_network.example.id
				purpose = "REGIONAL_MANAGED_PROXY"
			  }

			  resource "google_compute_network" "example" {
			  }

			  resource "google_compute_firewall" "example" {
				network = google_compute_network.example.name
			}
`,
			expected: []compute.Network{
				{
					Firewall: &compute.Firewall{},
					Subnetworks: []compute.SubNetwork{
						{
							Purpose: iacTypes.StringTest("REGIONAL_MANAGED_PROXY"),
						},
					},
				},
			},
		},
		{
			name: "private_ip_google_access_enabled",
			terraform: `
			resource "google_compute_subnetwork" "example" {
				name          = "test-subnetwork"
				network       = google_compute_network.example.id
				private_ip_google_access = true
			}
			resource "google_compute_network" "example" {
				name = "test-network"
			}
			`,
			expected: []compute.Network{
				{
					Subnetworks: []compute.SubNetwork{
						{
							Name:                  iacTypes.StringTest("test-subnetwork"),
							Purpose:               iacTypes.StringTest("PRIVATE_RFC_1918"),
							PrivateIPGoogleAccess: iacTypes.BoolTest(true),
						},
					},
				},
			},
		},
		{
			name: "firewall without ports",
			terraform: `resource "google_compute_firewall" "example" {
  network       = "test"
  source_ranges = ["1.2.3.4/32"]
  allow {
    protocol = "tcp"
  }
}
`,
			expected: []compute.Network{
				{
					Firewall: &compute.Firewall{
						IngressRules: []compute.IngressRule{
							{
								FirewallRule: compute.FirewallRule{
									Enforced: iacTypes.BoolTest(true),
									IsAllow:  iacTypes.BoolTest(true),
									Protocol: iacTypes.StringTest("tcp"),
									Ports: []common.PortRange{
										{
											End: iacTypes.IntTest(65535),
										},
									},
								},
								SourceRanges: []iacTypes.StringValue{
									iacTypes.StringTest("1.2.3.4/32"),
								},
							},
						},
					},
				},
			},
		},
	}

	for _, test := range tests {
		t.Run(test.name, func(t *testing.T) {
			modules := tftestutil.CreateModulesFromSource(t, test.terraform, ".tf")
			adapted := adaptNetworks(modules)
			testutil.AssertDefsecEqual(t, test.expected, adapted)
		})
	}
}
