#!/usr/bin/env bash
set -euo pipefail

# aws-network-segmentation-validation.sh
#
# Purpose:
#   Validate a network segmentation plan for AWS virtualization before rollout.
#   This script is intentionally non-destructive: it does not change AWS resources.
#
# What it checks:
#   - Required inputs exist
#   - Zone and dependency definitions are readable
#   - Expected ports/protocols are present in the dependency map
#   - Optional route and security group inspection commands are provided
#   - A validation checklist is printed for manual verification
#
# Inputs:
#   --zones FILE            YAML/CSV/plain-text file describing trust zones
#   --deps FILE             YAML/CSV/plain-text file describing dependencies
#   --checks FILE           Optional checklist file for validation notes
#   --aws-profile NAME      Optional AWS CLI profile to use for read-only queries
#   --region REGION         Optional AWS region for read-only queries
#   --vpc-id VPCID          Optional VPC ID for read-only inspection
#   --dry-run               Print what would be inspected; do not run AWS CLI queries
#   --help                  Show usage
#
# Examples:
#   bash aws-network-segmentation-validation.sh \
#     --zones zones.txt \
#     --deps dependencies.csv \
#     --checks validation-notes.md \
#     --aws-profile my-readonly-profile \
#     --region us-east-1 \
#     --vpc-id vpc-0123456789abcdef0

usage() {
  cat <<'EOF'
Usage:
  aws-network-segmentation-validation.sh --zones FILE --deps FILE [options]

Required:
  --zones FILE       File describing trust zones
  --deps FILE        File describing dependencies

Optional:
  --checks FILE      Validation checklist or notes file
  --aws-profile NAME  AWS CLI profile for read-only queries
  --region REGION    AWS region for read-only queries
  --vpc-id VPCID     VPC ID for optional inspection
  --dry-run          Do not execute AWS CLI queries
  --help             Show this help
EOF
}

log() {
  printf '[%s] %s\n' "$(date +'%Y-%m-%dT%H:%M:%S%z')" "$*"
}

fail() {
  printf 'ERROR: %s\n' "$*" >&2
  exit 1
}

require_file() {
  local path="$1"
  [[ -n "$path" ]] || fail "Missing required file argument"
  [[ -f "$path" ]] || fail "File not found: $path"
  [[ -r "$path" ]] || fail "File is not readable: $path"
}

contains_text() {
  local file="$1"
  local pattern="$2"
  grep -Eiq "$pattern" "$file"
}

print_section() {
  printf '\n=== %s ===\n' "$1"
}

ZONES_FILE=""
DEPS_FILE=""
CHECKS_FILE=""
AWS_PROFILE=""
REGION=""
VPC_ID=""
DRY_RUN="false"

while [[ $# -gt 0 ]]; do
  case "$1" in
    --zones)
      ZONES_FILE="${2:-}"
      shift 2
      ;;
    --deps)
      DEPS_FILE="${2:-}"
      shift 2
      ;;
    --checks)
      CHECKS_FILE="${2:-}"
      shift 2
      ;;
    --aws-profile)
      AWS_PROFILE="${2:-}"
      shift 2
      ;;
    --region)
      REGION="${2:-}"
      shift 2
      ;;
    --vpc-id)
      VPC_ID="${2:-}"
      shift 2
      ;;
    --dry-run)
      DRY_RUN="true"
      shift
      ;;
    --help|-h)
      usage
      exit 0
      ;;
    *)
      fail "Unknown argument: $1"
      ;;
  esac
done

[[ -n "$ZONES_FILE" ]] || { usage; fail "--zones is required"; }
[[ -n "$DEPS_FILE" ]] || { usage; fail "--deps is required"; }

require_file "$ZONES_FILE"
require_file "$DEPS_FILE"

if [[ -n "$CHECKS_FILE" ]]; then
  require_file "$CHECKS_FILE"
fi

print_section "Input summary"
log "Zones file: $ZONES_FILE"
log "Dependencies file: $DEPS_FILE"
log "Checks file: ${CHECKS_FILE:-<none>}"
log "AWS profile: ${AWS_PROFILE:-<none>}"
log "Region: ${REGION:-<none>}"
log "VPC ID: ${VPC_ID:-<none>}"
log "Dry run: $DRY_RUN"

print_section "Basic file validation"
[[ -s "$ZONES_FILE" ]] || fail "Zones file is empty: $ZONES_FILE"
[[ -s "$DEPS_FILE" ]] || fail "Dependencies file is empty: $DEPS_FILE"
log "Files exist and are non-empty"

print_section "Zone content checks"
if contains_text "$ZONES_FILE" 'management'; then
  log "Found management zone reference"
else
  fail "Management zone not found in zones file"
fi

if contains_text "$ZONES_FILE" 'application'; then
  log "Found application zone reference"
else
  fail "Application zone not found in zones file"
fi

if contains_text "$ZONES_FILE" 'shared|services'; then
  log "Found shared-services reference"
else
  log "Shared-services reference not detected; ensure this is intentional"
fi

print_section "Dependency content checks"
if contains_text "$DEPS_FILE" 'tcp|udp|icmp|port'; then
  log "Dependency file appears to include protocol/port information"
else
  fail "Dependency file does not appear to include protocol or port details"
fi

if contains_text "$DEPS_FILE" 'management|admin|bastion|jump'; then
  log "Management access dependency reference found"
else
  log "No explicit management access reference detected"
fi

print_section "Validation checklist"
cat <<'EOF'
Manual verification items:
- Confirm management and application zones are separated by subnet, route table, or equivalent boundary.
- Confirm east-west traffic is allowed only for documented dependencies.
- Confirm administrative ports are not reachable from application subnets.
- Confirm shared services are reachable only on required ports.
- Confirm there are no broad temporary allow rules left in place.
- Confirm disallowed source zones cannot reach protected destinations.
- Confirm logging or monitoring records zone access attempts.
EOF

print_section "Optional read-only AWS inspection"
if [[ "$DRY_RUN" == "true" ]]; then
  log "Dry run enabled; skipping AWS CLI calls"
else
  if command -v aws >/dev/null 2>&1; then
    AWS_CMD=(aws)
    [[ -n "$AWS_PROFILE" ]] && AWS_CMD+=(--profile "$AWS_PROFILE")
    [[ -n "$REGION" ]] && AWS_CMD+=(--region "$REGION")

    if [[ -n "$VPC_ID" ]]; then
      log "Would inspect route tables and security groups for VPC: $VPC_ID"
      log "Example read-only command: ${AWS_CMD[*]} ec2 describe-route-tables --filters Name=vpc-id,Values=$VPC_ID"
      log "Example read-only command: ${AWS_CMD[*]} ec2 describe-security-groups --filters Name=vpc-id,Values=$VPC_ID"
    else
      log "No VPC ID provided; skipping AWS resource inspection"
    fi
  else
    log "AWS CLI not found; skipping optional AWS inspection"
  fi
fi

print_section "Result"
log "Segmentation validation completed. Review any warnings above before production rollout."