terraform {
  required_version = ">= 1.0"
  
  required_providers {
    cloudflare = {
      source  = "cloudflare/cloudflare"
      version = "~> 4.0"
    }
  }
  
  backend "s3" {
    # Configure your backend here
    # bucket = "your-terraform-state"
    # key    = "cloudflare/terraform.tfstate"
    # region = "us-east-1"
  }
}

provider "cloudflare" {
  api_token = var.cloudflare_api_token
}

# Variables
variable "cloudflare_api_token" {
  description = "Cloudflare API token"
  type        = string
  sensitive   = true
}

variable "zone_id" {
  description = "Cloudflare Zone ID"
  type        = string
}

variable "account_id" {
  description = "Cloudflare Account ID"
  type        = string
}

# Access Applications
resource "cloudflare_access_application" "portal" {
  zone_id          = var.zone_id
  name             = "Hybrid Cloud Portal"
  domain           = "portal.sankofa.nexus"
  session_duration = "24h"
  
  cors_headers {
    allowed_methods = ["GET", "POST", "PUT", "DELETE"]
    allowed_origins = ["https://portal.sankofa.nexus"]
    allow_credentials = true
  }
}

resource "cloudflare_access_application" "rancher" {
  zone_id          = var.zone_id
  name             = "Rancher UI"
  domain           = "rancher.sankofa.nexus"
  session_duration = "4h"
}

resource "cloudflare_access_application" "argocd" {
  zone_id          = var.zone_id
  name             = "ArgoCD GitOps"
  domain           = "argocd.sankofa.nexus"
  session_duration = "8h"
}

resource "cloudflare_access_application" "grafana" {
  zone_id          = var.zone_id
  name             = "Grafana Dashboards"
  domain           = "grafana.sankofa.nexus"
  session_duration = "24h"
}

resource "cloudflare_access_application" "vault" {
  zone_id          = var.zone_id
  name             = "HashiCorp Vault"
  domain           = "vault.sankofa.nexus"
  session_duration = "2h"
}

resource "cloudflare_access_application" "keycloak" {
  zone_id          = var.zone_id
  name             = "Keycloak Admin"
  domain           = "keycloak.sankofa.nexus"
  session_duration = "2h"
}

# Access Policies
resource "cloudflare_access_policy" "portal_authenticated" {
  application_id = cloudflare_access_application.portal.id
  zone_id        = var.zone_id
  name           = "Allow Authenticated Users"
  decision       = "allow"
  precedence     = 1
  
  include {
    email_domain = "sankofa.nexus"
  }
}

resource "cloudflare_access_policy" "portal_admin_mfa" {
  application_id = cloudflare_access_application.portal.id
  zone_id        = var.zone_id
  name           = "Require MFA for Admins"
  decision       = "allow"
  precedence     = 2
  
  include {
    group = cloudflare_access_group.admins.id
  }
  
  require {
    mfa = true
  }
}

# Access Groups
resource "cloudflare_access_group" "admins" {
  account_id = var.account_id
  name       = "admins"
  
  include {
    email_domain = "sankofa.nexus"
  }
  
  require {
    email = ["admin@sankofa.nexus"]
  }
}

resource "cloudflare_access_group" "platform_engineers" {
  account_id = var.account_id
  name       = "platform-engineers"
  
  include {
    email_domain = "sankofa.nexus"
  }
}

resource "cloudflare_access_group" "employees" {
  account_id = var.account_id
  name       = "employees"
  
  include {
    email_domain = "sankofa.nexus"
  }
}

# Tunnels
resource "cloudflare_tunnel" "control_plane" {
  account_id = var.account_id
  name       = "control-plane-tunnel"
  secret     = var.tunnel_secret_control_plane
}

resource "cloudflare_tunnel" "proxmox_site_1" {
  account_id = var.account_id
  name       = "proxmox-site-1-tunnel"
  secret     = var.tunnel_secret_site_1
}

resource "cloudflare_tunnel" "proxmox_site_2" {
  account_id = var.account_id
  name       = "proxmox-site-2-tunnel"
  secret     = var.tunnel_secret_site_2
}

resource "cloudflare_tunnel" "proxmox_site_3" {
  account_id = var.account_id
  name       = "proxmox-site-3-tunnel"
  secret     = var.tunnel_secret_site_3
}

# Tunnel Routes
resource "cloudflare_tunnel_route" "control_plane" {
  account_id = var.account_id
  tunnel_id  = cloudflare_tunnel.control_plane.id
  network    = "10.0.0.0/16"
  comment    = "Control plane network"
}

resource "cloudflare_tunnel_route" "site_1" {
  account_id = var.account_id
  tunnel_id  = cloudflare_tunnel.proxmox_site_1.id
  network    = "10.1.0.0/16"
  comment    = "Proxmox site 1 network"
}

resource "cloudflare_tunnel_route" "site_2" {
  account_id = var.account_id
  tunnel_id  = cloudflare_tunnel.proxmox_site_2.id
  network    = "10.2.0.0/16"
  comment    = "Proxmox site 2 network"
}

resource "cloudflare_tunnel_route" "site_3" {
  account_id = var.account_id
  tunnel_id  = cloudflare_tunnel.proxmox_site_3.id
  network    = "10.3.0.0/16"
  comment    = "Proxmox site 3 network"
}

# Gateway Policies
resource "cloudflare_teams_list" "blocked_domains" {
  account_id = var.account_id
  name       = "Blocked Domains"
  type       = "DOMAIN"
  items      = [
    "malware.example.com",
    "phishing.example.com"
  ]
}

resource "cloudflare_teams_rule" "block_malicious" {
  account_id  = var.account_id
  name        = "Block Malicious Domains"
  description = "Block known malicious domains"
  precedence  = 1
  action      = "block"
  
  filters = ["dns"]
  
  rule_settings {
    block_page_enabled = true
    block_reason      = "This domain is blocked by security policy"
  }
}

# Outputs
output "tunnel_ids" {
  value = {
    control_plane = cloudflare_tunnel.control_plane.id
    site_1        = cloudflare_tunnel.proxmox_site_1.id
    site_2        = cloudflare_tunnel.proxmox_site_2.id
    site_3        = cloudflare_tunnel.proxmox_site_3.id
  }
}

output "application_ids" {
  value = {
    portal   = cloudflare_access_application.portal.id
    rancher  = cloudflare_access_application.rancher.id
    argocd   = cloudflare_access_application.argocd.id
    grafana  = cloudflare_access_application.grafana.id
    vault    = cloudflare_access_application.vault.id
    keycloak = cloudflare_access_application.keycloak.id
  }
}

