name: Sync Newly Created Browser Monitor Scripts to Sematext Cloud 
on:
  push:
    branches:
      - master

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
        with:
          fetch-depth: 0

      - name: Detect changed files
        id: changed-files
        uses: tj-actions/changed-files@v41
        with:
          since_last_remote_commit: 'true'
          separator: ","

      - name: Send newly created scripts to Sematext Cloud (Action will create a Browser monitor for each added script)
        env:
          SC_API_BASE_URL: ${{ secrets.SC_API_BASE_URL }}
          SC_API_KEY: ${{ secrets.SC_API_KEY }}
        run: |

          IFS=',' read -r -a addedFiles <<< "${{ steps.changed-files.outputs.added_files }}"
          IFS=',' read -r -a renamedFiles <<< "${{ steps.changed-files.outputs.renamed_files }}"

          filesArray=("${addedFiles[@]}" "${renamedFiles[@]}")

          errors=()

          length=${#filesArray[@]}

          if [ $length == 0 ]; then
            echo 'No added files found.'
          fi

          echo "SKIP_COMMIT=1" >> $GITHUB_ENV

          echo 'Files to be synced:'
          for i in $(echo "${!filesArray[@]}"); do
            file=$(echo ${filesArray[$i]})
            echo $file
            if [[ $file == *"browser_monitor_scripts"* ]]; then
              script_content=$( base64 -w 0 "$file" )


              #read the first line of the script and get app ID and monitor IDs
              line=$( head -n 1 "$file" )
              IFS=';' read -r -a ids <<< "$line"

              length=${#ids[@]}

              if [ $length == 0 ]; then
                  echo '::warning:: App ID must be specified on the first line using the format //appId=1; '
                  errors+=("$file")
                  continue
              fi

              #if only APP ID is passed, create new browser monitor
              if [ $length == 1 ]; then

                IFS='=' read -r -a app_id <<< "${ids[0]}"
                app_id_length=${#app_id[@]}

                if [ $app_id_length != 2 ]; then
                    echo '::warning:: App ID not found. App ID must be specified on the first line using the format //appId=1; or alternatively if you are adding a script for an existing monitor you have to specify the monitor ID as well, in the format //appId=1;monitorId=2,3'
                    errors+=("$file")
                    continue
                fi
                app_id=${app_id[1]}

                #remove whitespaces
                app_id="$(echo -e "${app_id}" | tr -d '[[:space:]]')"

                #create request body with default values

                IFS='/' read -r -a file_name_parsed <<< "$file"
                index=${#file_name_parsed[@]}-1
                name=${file_name_parsed[$index]}
                scriptBased=true
                enabled=true
                isGitHubSync=true
                body='{"name":"'$name'","interval":"1h","locations":[1],"scriptBased":'$scriptBased',"enabled":'$enabled',"script":"'$script_content'","isGitHubSync":'$isGitHubSync'}'

                api_url=${SC_API_BASE_URL}'/synthetics-api/api/v3/apps/'${app_id}'/monitors/browser'

                  curl --location --request POST ${api_url} \
                    --header 'authorization: apiKey '${SC_API_KEY} \
                      --header 'Content-Type: application/json' \
                        --data-raw "$body" > result.txt

                  cat result.txt
                  if [ $(head -1 result.txt | grep -c '"success":false') -ne 0 ]; then
                    echo '::warning:: Sync script API request failed';
                    errors+=("$file")
                    break
                  else
                    #update file with app ID and monitor ID comment so it can be synced later when update occurs
                    first_line=$( head -1 result.txt )
                    monitor_id=`echo $first_line | jq '.data.id'`
                    comment='\/\/appId='$app_id';monitorId='$monitor_id''
                    sed -i "1s/.*/$comment/" "$file"

                    echo "SKIP_COMMIT=0" >> $GITHUB_ENV
                  fi
              fi

              #if both App ID and Monitor ID are passed, try to update existing browser monitor
              if [ $length == 2 ]; then
                scriptBased=true
                body='{"scriptBased":'$scriptBased',"script":"'$script_content'"}'

                IFS='=' read -r -a app_id <<< "${ids[0]}"

                app_id_length=${#app_id[@]}
                if [ $app_id_length != 2 ]; then
                    echo '::warning:: App ID not found. App ID and monitor IDs must be specified on the first line using the format //appId=1;monitorId=2,3'
                    errors+=("$file")
                    continue
                fi

                app_id=${app_id[1]}

                #remove whitespaces
                app_id="$(echo -e "${app_id}" | tr -d '[[:space:]]')"

                IFS='=' read -r -a monitor_ids <<< "${ids[1]}"
                monitor_ids=${monitor_ids[1]}

                monitor_ids_length=${#monitor_ids[@]}
                if [ $monitor_ids_length != 2 ]; then
                    echo '::warning:: Monitor ID not found. App ID and monitor IDs must be specified on the first line using the format //appId=1;monitorId=2,3'
                    errors+=("$file")
                    continue
                fi

                IFS=',' read -r -a monitors <<< "$monitor_ids"

                #send update request to Sematext API for each monitor ID
                for monitor_id in "${monitors[@]}"; do
                  #remove whitespaces from monitor id
                  monitor_id="$(echo -e "${monitor_id}" | tr -d '[[:space:]]')"
                  api_url=${SC_API_BASE_URL}'/synthetics-api/api/v3/apps/'${app_id}'/monitors/browser/'${monitor_id}
                  curl -s --location --request PUT ${api_url} \
                    --header 'authorization: apiKey '${SC_API_KEY} \
                      --header 'Content-Type: application/json' \
                        --data-raw $body > result.txt

                  cat result.txt
                  if [ $(head -1 result.txt | grep -c '"success":false') -ne 0 ]; then
                    echo '::warning:: Sync script API request failed';
                    errors+=("$file")
                    break
                  fi

                done
              fi

            fi
          done

          if (( ${#errors[@]} )); then
            echo '::warning:: The following scripts are not synced, please check workflow logs for more details:'
            for error in "${errors[@]}"; do
              echo '    file name: '$error
            done
            exit 1
          fi

      - name: Commit files # commit updated scripts with comment //app_id=x;monitor_id=y
        run: |
          if [ $SKIP_COMMIT -eq 0 ]; then
            git config --local user.name "SematextSyncBot"
            git add ./browser_monitor_scripts
            git commit -m "Updating scripts"
            git push
          fi
