#!/bin/bash

# CSV file structure:
# EMAIL_ACCOUNT EMAIL_PASSWORD_SRC EMAIL_HOST_SRC EMAIL_ADDRESS

# CSV field explanation
# EMAIL_ACCOUNT: Name of the old email account on the source server. i.e. wp1234567-mm
# EMAIL_PASSWORD_SRC: Password for the email account on the source server
# EMAIL_HOST_SRC: Hostname of the source server. i.e.  wp1234567.server-he.de
# EMAIL_ADDRESS: Primary email address for the account on the destination server. Must be unique and the domain must exist on the destination server

# General notes on CSV
# All fields in a row must be filled
# Delimiter is "€", since all other characters might be used in the passwords.
# Upper case letters may only be used in passwords

# Usage
# Clone the he_migration_cwh_fms_plesk repo from code.wartung.xyz to /tmp/
# run /tmp/he_migration_cwh_fms_plesk/update_server_plesk_migration_cwh.sh to make sure the server is setup correctly
# Save the csv, see above, to /tmp/migration_csv
# run /tmp/he_migration_cwh_fms_plesk/create_email_plesk_accounts.sh -f /tmp/migration_csv/MY_MAIL_CREATE.csv

# Ensure the log directory exists
mkdir -p /tmp/migration_logs/

# Get the filename of current script and strip .sh from the end
SCRIPT_FILE_NAME=$(basename "$0" .sh)

# Create the log and error filenames
LOG_FILE_NAME="/tmp/migration_logs/$SCRIPT_FILE_NAME.log"
ERR_FILE_NAME="/tmp/migration_logs/$SCRIPT_FILE_NAME.err"

# Print info about logging
echo "STDOUT redirected to $LOG_FILE_NAME"
echo "STDERR redirected to $ERR_FILE_NAME"

# Check if the necessary argument is provided
if [[ "$#" -lt 1 ]]; then
    echo "Usage: $0 -f <path_to_csv_file>"
    exit 1
fi

# Parse arguments
while getopts "f:" opt; do
    case $opt in
        f) CSV_FILE="$OPTARG" ;;
        *)
            echo "Invalid option: -$OPTARG"
            exit 1
            ;;
    esac
done

# Ensure the CSV file exists
if [[ ! -f "$CSV_FILE" ]]; then
    echo "Error: CSV file not found at $CSV_FILE"
    exit 1
fi

# Making sure CSV files formatting is correct
echo "Checking $CSV_FILE for BOM, CRLF, White Spaces and Empty Lines"
  # Remove BOM (Byte Order Mark) from $CSV_FILE
  sed -i '1s/^\xEF\xBB\xBF//' "$CSV_FILE"
  
  # Remove CRLF (Windows Line Endings) from $CSV_FILE
  sed -i 's/\r$//' "$CSV_FILE"

  # Remove all spaces and tabs
  sed -i 's/ //g' "$CSV_FILE"

  # Remove empty lines
  sed -i '/^$/d' "$CSV_FILE"
echo "Done converting $CSV_FILE"

# Function to generate random password
GENERATE_PASSWORD() {
  tr -dc A-Za-z0-9 </dev/urandom | head -c 12
}

# Arrays for summary
SUCCESSFUL=()
FAILED=()

# Regex to check format of email address
EMAIL_REGEX='^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}(\.[a-zA-Z]{2,})?$'

# Read CSV and process each line
HEADER_PROCESSED=false
while IFS='€' read -r EMAIL_ACCOUNT EMAIL_PASSWORD_SRC EMAIL_HOST_SRC EMAIL_ADDRESS; do
  # Skip empty lines
  if [[ -z "$EMAIL_ACCOUNT" || -z "$EMAIL_ADDRESS" ]]; then
      continue
  fi

    # Skip the header line if it exists
  if [[ "$HEADER_PROCESSED" == false ]]; then
    if [[ "$EMAIL_ACCOUNT" == "EMAIL_ACCOUNT" && "$EMAIL_PASSWORD_SRC" == "EMAIL_PASSWORD_SRC" && "$EMAIL_HOST_SRC" == "EMAIL_HOST_SRC" && "$EMAIL_ADDRESS" == "EMAIL_ADDRESS" ]]; then
      HEADER_PROCESSED=true
      continue
    fi
      HEADER_PROCESSED=true
  fi
  
  # Validate email format
  if ! [[ "$EMAIL_ADDRESS" =~ $EMAIL_REGEX ]]; then
    FAILED+=("$EMAIL_ADDRESS Invalid email format")
    continue
  fi

  # Extract domain from email
  EMAIL_DOMAIN="${EMAIL_ADDRESS##*@}"
    
  # Check if domain exists in Plesk
  if ! plesk bin domain --info "$EMAIL_DOMAIN" &>/dev/null; then
    FAILED+=("$EMAIL_ADDRESS (Domain does not exist)")
    continue
  fi

  # Check if email account already exists
  if plesk bin mail --info "$EMAIL_ADDRESS" &>/dev/null; then
    FAILED+=("$EMAIL_ADDRESS (Email already exists)")
    continue
  fi
    
  # Generate random password if not provided
  EMAIL_PASSWORD_DST=$(GENERATE_PASSWORD)

  # Convert $EMAIL_ADDRESS to lower case.
  EMAIL_ADDRESS="${EMAIL_ADDRESS,,}"

  # Create email account
  echo "Creating mail account $EMAIL_ADDRESS" 
  if plesk bin mail --create "$EMAIL_ADDRESS" -passwd "$EMAIL_PASSWORD_DST" -mailbox true >> "$LOG_FILE_NAME" 2>> "$ERR_FILE_NAME"; then
    SUCCESSFUL+=("$EMAIL_ADDRESS")
  else
    FAILED+=("$EMAIL_ADDRESS (Creation failed)")
  fi
done < <(tail -n +1 "$CSV_FILE")

# Print summary
echo "Summary:"
echo "---------"
echo "Successfully created entries:"
for ITEM in "${SUCCESSFUL[@]}"; do
  echo "  - $ITEM"
done
echo "---------"
echo "Failed to create entries:"
for ITEM in "${FAILED[@]}"; do
  echo "  - $ITEM"
done
echo "---------"