#!/bin/bash -eu

if [[ ( -z "${TESLAFI_API_TOKEN:+x}" ) && ( -z "${TESSIE_API_TOKEN:+x}" ) && ( -z "${TESLA_BLE_VIN:+x}" ) ]]
then
  log "Not configured to keep car awake."
else
  function nudge {
    local retry=1

    while true
    do
      if [[ -n "${TESSIE_API_TOKEN:+x}" ]]
      # Use Tessie API to nudge the car
      then
        http_response=$(curl -s -w "%{http_code}" \
          -H "Authorization: Bearer $TESSIE_API_TOKEN" \
          -H "Accept: application/json" \
          -H "User-Agent: github.com/marcone/teslausb" \
          "https://api.tessie.com/$TESSIE_VIN/command/close_charge_port")

        # Extract HTTP status code
        http_status="${http_response: -3}"
        
        # Check if HTTP status code is not 200 (OK)
        if [ "$http_status" != "200" ]
        then
          # Log an error
          log "Tessie: Failed to send command. Check your TESSIE_API_TOKEN and TESSIE_VIN are set correctly. If they are, your car may be offline or asleep."
          if [ "$retry" -lt "3" ]
          then
            log "Tessie: Retrying after 30s in case the connection was poor."
            retry=$((retry+1))
            sleep 30
            continue
          else
            log "Tessie: Connection to the internet likely broken."
            break
          fi
        fi
      fi

      if [[ -n "${TESLA_BLE_VIN:+x}" ]]
      # use Tesla BLE API to nudge the car
      then
        if ! BLE_response=$(/root/bin/tesla-control -ble -key-file /root/.ble/key_private.pem -vin "${TESLA_BLE_VIN^^}" charge-port-close 2>&1)
        then
          # check false-negative BLE responses
          if [[ ( "$BLE_response" != *"already closed"* ) && ( "$BLE_response" != *"cable connected"* ) ]]
          then
            # log error and retry
            log "Tesla BLE: Failed to nudge the car. There may be an issue with the BLE communication."
            if [ "$retry" -lt "3" ]
            then
              log "Tesla BLE: Retrying after 30s in case the connection was poor."
              retry=$((retry+1))
              sleep 30
              continue
            else
              log "Tesla BLE: $BLE_response"
              break
            fi
          fi
        fi
      fi

      sleep 300
      retry=1
    done
  }

  case "${SENTRY_CASE}" in
    1)
      # Sentry Mode should already be enabled
      log "Skip sending command to enable Sentry Mode."
      ;;
    2)
      if [[ ( -n "${TESLAFI_API_TOKEN:+x}" ) ]]
      # Use TeslaFi API to enable Sentry Mode
      then
        http_response=$(curl -s -w "%{http_code}" \
          -H "Authorization: Bearer $TESLAFI_API_TOKEN" \
          -H "Accept: application/json" \
          -H "User-Agent: github.com/marcone/teslausb" \
          "https://www.teslafi.com/feed.php?command=set_sentry_mode&sentryMode=true&noWake=true")

        log "TeslaFi: Command sent to enable Sentry Mode."

        # Extract HTTP status code
        http_status="${http_response: -3}"
                
        # Extract response body (excluding status code)
        response_body="${http_response:0:${#http_response}-3}"

        # Check if HTTP status code is not 200 (OK)
        if [ "$http_status" != "200" ]
        then
          # Log an error
          log "TeslaFi: Failed to set Sentry Mode. Check your TESLAFI_API_TOKEN is set correctly. If it is, your car may be offline or asleep."
        else
          # Check if the response is in JSON format
          if ! jq -e . >/dev/null 2>&1 <<<"$response_body"
          then
            log "TeslaFi: Failed to set Sentry Mode."
          else
            # Parse JSON and check if "result" is true
            result1=$(jq -r '.response' <<<"$response_body")
            result2=$(jq -r '.result' <<<"$result1")
            request_counter=$(jq -r '.tesla_request_counter' <<<"$response_body")
            commands=$(jq -r '.commands' <<<"$request_counter")

            if [[ "$result2" = "true" ]]
            then
              log "TeslaFi: Sentry Mode Enabled. Monthly command counter = $commands."
            else
              log "TeslaFi: Failed to set Sentry Mode. Response data: $response_body"
            fi
          fi
        fi
      elif [[ -n "${TESSIE_API_TOKEN:+x}" ]]
      # Use Tessie API to enable Sentry Mode
      then
        http_response=$(curl -s -w "%{http_code}" \
          -H "Authorization: Bearer $TESSIE_API_TOKEN" \
          -H "Accept: application/json" \
          -H "User-Agent: github.com/marcone/teslausb" \
          "https://api.tessie.com/$TESSIE_VIN/command/enable_sentry")

        log "Tessie: Command sent to enable Sentry Mode."
        # Extract HTTP status code
        http_status="${http_response: -3}"
        
        # Extract response body (excluding status code)
        response_body="${http_response:0:${#http_response}-3}"
        
        # Check if HTTP status code is not 200 (OK)
        if [ "$http_status" != "200" ]
        then
          # Log an error
          log "Tessie: Failed to set Sentry Mode. Check your TESSIE_API_TOKEN and TESSIE_VIN are set correctly. If they are, your car may not have a good connection."
        else
          # Check if the response is in JSON format
          if ! jq -e . >/dev/null 2>&1 <<<"$response_body"
          then
            log "Tessie: Failed to set Sentry Mode. Response data: $response_body"
          else
            # Parse JSON and check if "result" is true
            result=$(jq -r '.result' <<<"$response_body")
            if [[ "$result" != "true" ]]
            then
              log "Tessie: Failed to set Sentry Mode. Response data: $response_body"
            fi
          fi
        fi
      elif [[ -n "${TESLA_BLE_VIN:+x}" ]]
      # Use Tesla BLE API to enable Sentry Mode
      then
        if /root/bin/tesla-control -ble -key-file /root/.ble/key_private.pem -vin "${TESLA_BLE_VIN^^}" sentry-mode on
        then
          log "Tesla BLE: Command sent to enable Sentry Mode."
        else
          log "Tesla BLE: Failed to set Sentry Mode."
        fi
      fi
      ;;
    3)
      # Nudge car periodically without using Sentry Mode
      log "Starting background task to keep car awake."
      nudge &
      echo $! > /tmp/keep_awake_task_pid
      ;;
    *)
      log "Invalid or no SENTRY_CASE defined."
      ;;
  esac
fi
