#!/bin/bash

############################################################
# functions
#===========================================================

attachigw()
{
  [[ ${#vpcid} -eq 0 ]] && vpcid=$(idvpcid)
  [[ ${#igwid} -eq 0 ]] && igwid=$(idigwid)
  [[ ${#vpcid} -eq 0 ]] && return 3
  [[ ${#igwid} -eq 0 ]] && return 5

  tid=$(aws ec2 describe-internet-gateways \
    --query \
  "InternetGateways[?Attachments[?VpcId=='${vpcid}' && State=='available']].InternetGatewayId" \
    --output text)
  if [ ${#tid} -ne 0 ]
  then
    [[ "${tid}" == "${igwid}" ]] && return 0 || return 6
  fi
    
  aws ec2 attach-internet-gateway \
    --vpc-id ${vpcid} \
    --internet-gateway-id ${igwid}

  return $?
}

mkec2()
{
  iid=$(idinstanceid)
  if [ ${#iid} -eq 0 ]
  then
    echo "Creating ec2 instance: ${iname}"
    ami=$(idami)
    subid=$(subassoc)
    sgid=$(idsgid)
    aws ec2 run-instances \
      --image-id ${ami} \
      --count 1 \
      --instance-type ${itype} \
      --key-name ${keyname} \
      --subnet-id ${subid} \
      --associate-public-ip-address \
      --security-group-ids ${sgid} \
      --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=${iname}}]" > /dev/null
  fi

  iid=$(idinstanceid)
  idistate ${iid} | grep -qi running
  while [ $? -ne 0 ]
  do
    echo "... Waiting for ${iname} to be available"
    sleep 2
    idistate ${iid} | grep -qi running
  done
    
}

mkigw()
{
  snetid=$(idsubnetid ${vpcid} ${subcidrs[${x}]})

  igwid=$(idigwid)
  [[ ${#igwid} -gt 0 ]] && return 0

  echo "Creating internet gateway: ${igwname}"
  aws ec2 create-internet-gateway --tag-specifications \
  "ResourceType=internet-gateway,Tags=[{Key=Name,Value=${igwname}}]"  > /dev/null

  return $?
}

mkrole()
{
  aws iam list-roles --query 'Roles[*].RoleName' --output yaml | \
    grep -q ${rolename} 
  if [ $? -ne 0 ]
  then
    echo "Creating ${rolename}"
    aws iam create-role --role-name ${rolename} \
      --assume-role-policy-document "$(cat <<EOF
${AssumeRole}
EOF
)" > /dev/null
  fi
  [[ $? -ne 0 ]] && return $?
  aws iam list-policies --no-paginate --query 'Policies[].PolicyName' --output yaml > b
  grep -q ${policyname} b
  if [ $? -ne 0 ]
  then
    echo "Creating ${policyname}"
    aws iam create-policy --policy-name ${policyname} \
      --policy-document "$(cat <<eof
${Policy}
eof
)" > /dev/null
  fi
  [[ $? -ne 0 ]] && return $?
}

mkroutes()
{

  [[ ${#vpcid} -eq 0 ]] && vpcid=$(idvpcid)
  [[ ${#vpcid} -eq 0 ]] && exit 3
  [[ ${#igwid} -eq 0 ]] && igwid=$(idigwid)
  [[ ${#igwid} -eq 0 ]] && exit 6
  
  rtableid=$(idrtable)
  if [ ${#rtableid} -eq 0 ] 
  then
    echo "Creating route table: ${rtablename}"
    aws ec2 create-route-table --vpc-id ${vpcid} --tag-specifications \
      "ResourceType=route-table,Tags=[{Key=Name,Value='${rtablename}'}]" > /dev/null
  fi
  [[ ${#rtablieid} -eq 0 ]] && rtableid=$(idrtable)

  rstate=$(aws ec2 describe-route-tables \
    --route-table-id ${rtableid} --query \
    "RouteTables[*].Routes[?DestinationCidrBlock == '0.0.0.0/0'].State" \
    --output text)
  if [ ${#rstate} -eq 0 ]
  then
    echo "Creating route via ${igwname}"
    aws ec2 create-route --route-table-id ${rtableid}  --destination-cidr-block 0.0.0.0/0 \
      --gateway-id ${igwid} > /dev/null
  fi

  [[ ${#subid} -eq 0 ]] && subid=$(idsubnetid ${vpcid} ${subcidrs[0]})
  assocsubid=$(subassoc)
  if [ ${#assocsubid} -eq 0 ]
  then
    echo "Associating ${rtablename} with ${subnames[0]}"
    echo "aws ec2 associate-route-table --subnet-id ${subid} --route-table-id ${rtableid} > /dev/null"
    aws ec2 associate-route-table --subnet-id ${subid} --route-table-id ${rtableid} > /dev/null
  fi

  plist=$(aws ec2 describe-managed-prefix-lists \
    --region ${region}  --query \
    "PrefixLists[?PrefixListName=='com.amazonaws.${region}.s3'].PrefixListId" \
    --output text)
  already=$(aws ec2 describe-route-tables --route-table-id ${rtableid} --query \
    "RouteTables[*].Routes[?DestinationPrefixListId=='${plist}'].State" \
    --output text)
  if [ ${#already} -eq 0 ]
  then
    echo "Creating s3 gateway endpoint in ${rtablename}"
    aws ec2 create-vpc-endpoint --vpc-id ${vpcid} \
    --service-name com.amazonaws.${region}.s3 \
    --vpc-endpoint-type Gateway --route-table-ids ${rtableid} > /dev/null
  fi

  epid=$(aws ec2 describe-vpc-endpoints \
    --filters Name=service-name,Values=com.amazonaws.${region}.secretsmanager \
      Name=vpc-id,Values=${vpcid} \
    --query "VpcEndpoints[?VpcId=='${vpcid}' && \
      ServiceName=='com.amazonaws.${region}.secretsmanager'].VpcEndpointId" \
    --output text)
  if [ ${#epid} -eq 0 ]
  then
    echo "Enableing DNS support required for interface endpoints"
    aws ec2 modify-vpc-attribute --vpc-id ${vpcid} --enable-dns-support "{\"Value\":true}"
    aws ec2 modify-vpc-attribute --vpc-id ${vpcid} --enable-dns-hostnames "{\"Value\":true}"

    echo "Creating secrets manager interface endpoint in ${rtablename}"
    aws ec2 create-vpc-endpoint --vpc-id ${vpcid} \
      --service-name com.amazonaws.${region}.secretsmanager \
      --vpc-endpoint-type Interface --subnet-ids ${asssocsubid} > /dev/null
  fi
}

mksg()
{
  [[ ${#vpcid} -eq 0 ]] && vpcid=$(idvpcid)

  sgid=$(idsgid)
  if [ ${#sgid} -eq 0 ]
  then
    echo "Creating ${sgname}: ${sgdesc}"
    aws ec2 create-security-group --group-name ${sgname} \
      --description "${sgdesc}" --vpc-id ${vpcid} > /dev/null
  fi
  sgid=$(idsgid)
  [[ ${#sgid} -eq 0 ]] && exit 8

  aws ec2 describe-security-groups --group-ids ${sgid} | grep -qi "${myip}/32"
  if [ $? -ne 0 ]
  then
    echo "Creating ingress rule"
    aws ec2 authorize-security-group-ingress \
      --group-id ${sgid} --protocol tcp --port 22 \
      --cidr ${myip}/32 > /dev/null
  fi
}

mksubnets()
{
  [[ ${#vpcid} -eq 0 ]] && vpcid=$(idvpcid)
  while [ "${vpcid}" == "None" ]
  do
    sleep 2
    vpcid=$(idvpcid)
  done
  echo "VPCID: ${vpcid}"
  x=0; while [ ${x} -lt ${#subcidrs[*]} ]
  do
    snetid=$(idsubnetid ${vpcid} ${subcidrs[${x}]})
    if [ ${#snetid} -eq 0 ]
    then
      echo "Creating subnet: ${subnames[${x}]}: ${subcidrs[${x}]}"
      subid=$(aws ec2 create-subnet --vpc-id ${vpcid} \
        --cidr-block ${subcidrs[${x}]}  \
        --query Subnet.SubnetId --output text \
        --tag-specifications \
        "ResourceType=subnet,Tags=[{Key=Name,Value=${subnames[${x}]}"}])
      [[ ${#subid} -eq 0 ]] && return 3
    # ${subids[${x}]}=${subid}
    fi
    x=$((x+1))
  done
}

mkvpc()
{
  vpcid=$(idvpcid)
  if [ ${#vpcid} -eq 0 ]
  then
    echo "Creating vpc: ${vpcname} with cidr: ${vpcidr}"
    vpcid=$(aws ec2 create-vpc --cidr-block "${vpcidr}" \
      --tag-specifications \
        "ResourceType=vpc,Tags=[{Key=Name,Value=${vpcname}}]" \
      --query VpcId --output text)
    sleep 10 # give vpc time to settle
  fi
}

############################################################
# main
#===========================================================

[[ -f ./vars ]] && source ./vars || exit 10

# mkrole    || exit 2
mkvpc     || exit 3
mksubnets || exit 4
mkigw     || exit 5
attachigw || exit 6
mkroutes  || exit 7
mksg      || exit 8
mkec2     || exit 9

exit 
############################################################
# Policy commands:
#===========================================================
#
# retrieve policy arn
# aws iam attach-role-policy --role-name dolrole-ub2s3-0x001 --policy-arn <Policy-ARN>

# $ aws iam list-policies --query "Policies[?PolicyName=='${policyname}'].{ARN:Arn}" --output text
# arn:aws:iam::320205061226:policy/dolpolicy-ec2-dols30x002
