#!/usr/bin/env bash
# This script is used to run initial setup of the pre-staging environment

set -e

PR_NUMBER=$1
INIT_CONFIG_PASSWORD_HASH=$2
INIT_CONFIG_ACCESS_TOKEN_HASH=$3
INIT_CONFIG_ACCESS_TOKEN=$4
INIT_CONFIG_PASSWORD=$5
FLOWFUSE_URL="${6:-$PR_NUMBER.flowfuse.dev}"


create_user() {
  local USERNAME=$1
  local PASSWORD="${INIT_CONFIG_PASSWORD}"

  echo "Creating $USERNAME user"
  curl -ks -w "\n" -XPOST \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" \
    -d '{
      "name": "'"$USERNAME"'",
      "username": "'"$USERNAME"'",
      "password": "'"$PASSWORD"'",
      "email": "'"$USERNAME@flowfuse.dev"'",
      "isAdmin": false,
      "createDefaultTeam": false
    }' "https://$FLOWFUSE_URL/api/v1/users/"
}

create_team() {
  local TEAM_TYPE_SELECTOR=$1
  local TEAM_NAME=$2
  local TEAM_TYPE_ID
  TEAM_TYPE_ID=$(curl -ks -XGET -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" https://$FLOWFUSE_URL/api/v1/team-types/ | jq -r --arg TYPE "$TEAM_TYPE_SELECTOR" '.types[] | select(.name==$TYPE) | .id')
  echo "Creating $TEAM_NAME team"
  curl -ks -w "\n" -XPOST \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" \
    -d '{
          "name":"'"$TEAM_NAME"'",
          "type":"'"$TEAM_TYPE_ID"'"
        }' https://$FLOWFUSE_URL/api/v1/teams/
}

get_team_id() {
  local TEAM_NAME=$1
  local TEAM_ID
  TEAM_ID=$(curl -ks -XGET -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" https://$FLOWFUSE_URL/api/v1/teams | jq -r --arg NAME "$TEAM_NAME" '.teams[] | select(.name==$NAME) | .id')
  echo "$TEAM_ID"
}

get_latest_image_tag() {
  local NR_VERSION=$1
  local IMAGE="flowfuse/node-red"
  local TOKEN
  local TAG
  TOKEN=$(curl -s "https://auth.docker.io/token?service=registry.docker.io&scope=repository:${IMAGE}:pull" | jq -r '.token')
  TAG=$(curl -s -H "Authorization: Bearer $TOKEN" https://registry-1.docker.io/v2/${IMAGE}/tags/list | jq -r '.tags[]' | grep -vE '^v' | grep "${NR_VERSION}" | sort -rV | head -n 1)
  echo "$TAG"
}

create_suspended_instance() {
  local INSTANCE_NAME=$1-$PR_NUMBER
  local TEAM_APPLICATION_ID=$2
  echo "Creating suspended $INSTANCE_NAME@$TEAM_APPLICATION_ID instance"
  
  local RESPONSE
  RESPONSE=$(curl -ks -XPOST \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" \
    -d '{
          "name": "'"$INSTANCE_NAME"'",
          "applicationId": "'"$TEAM_APPLICATION_ID"'",
          "projectType": "'"$projectTypeId"'",
          "stack": "'"$stackId"'",
          "template": "'"$templateId"'"
        }' https://$FLOWFUSE_URL/api/v1/projects/)
  
  echo "DEBUG: Raw response from API:"
  echo "$RESPONSE"
  echo "DEBUG: Response length: ${#RESPONSE}"

  # Check if response is valid JSON before parsing
  if echo "$RESPONSE" | jq . > /dev/null 2>&1; then
    INSTANCE_ID=$(echo "$RESPONSE" | jq -r '.id')
    echo "DEBUG: Successfully parsed instance ID: $INSTANCE_ID"
  else
    echo "ERROR: Invalid JSON response received"
    echo "DEBUG: Response from API:"
    echo "$RESPONSE"
    echo ""
    return 1
  fi
  
  sleep 5
  curl -ks -w "\n" -XPOST \
    -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" \
    https://$FLOWFUSE_URL/api/v1/projects/$INSTANCE_ID/actions/suspend
}

create_device() {
  local DEVICE_NAME=$1
  local DEVICE_TYPE=$2
  local TEAM_NAME=$3
  TEAM_ID=$(get_team_id "${TEAM_NAME}")
  echo "Creating $DEVICE_NAME@$TEAM_ID device"
  curl -ks -w "\n" -XPOST -o /dev/null \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" \
    -d '{
      "name": "'"$DEVICE_NAME"'",
      "type": "'"$DEVICE_TYPE"'",
      "team": "'"$TEAM_ID"'"
      }' https://$FLOWFUSE_URL/api/v1/devices/
}

create_stack() {
  local STACK_NAME=$1
  local STACK_LABEL=$2
  local STACK_CPU=$3
  local STACK_MEMORY=$4
  local STACK_CONTAINER=$5
  echo "Creating $STACK_NAME stack"
  projectTypeId=$(curl -ks -XGET -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" https://$FLOWFUSE_URL/api/v1/project-types/ | jq -r '.types[].id')
  curl -ks -w "\n" -XPOST \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" \
    -d '{"name":"'"$STACK_NAME"'","label":"'"$STACK_LABEL"'", "projectType":"'"$projectTypeId"'","properties":{ "cpu":'"$STACK_CPU"',"memory":'"$STACK_MEMORY"',"container":"'"$STACK_CONTAINER"'"}}' \
    https://$FLOWFUSE_URL/api/v1/stacks/
}

### Create first user
DBPASSWORD=$(kubectl --namespace "pr-$PR_NUMBER" get secret flowfuse-pr-$PR_NUMBER-postgresql -o jsonpath='{.data.password}' | base64 -d)
kubectl run flowfuse-setup-0 \
  --namespace "pr-$PR_NUMBER" \
  -it --rm \
  --restart=Never \
  --env="PGPASSWORD=$DBPASSWORD" \
  --image bitnami/postgresql:14.10.0-debian-11-r3 \
  -- psql -h flowfuse-pr-$PR_NUMBER-postgresql -U forge -d flowforge -c \
  "INSERT INTO public.\"Users\" (username,name,email,email_verified,sso_enabled,mfa_enabled,\"password\",password_expired,\"admin\",avatar,tcs_accepted,suspended,\"createdAt\",\"updatedAt\",\"defaultTeamId\") \
    VALUES ('flowfusedeveloper','flowfusedeveloper','noreply@flowfuse.dev',true,false,false,'$INIT_CONFIG_PASSWORD_HASH',false,true,'/avatar/Zmxvd2Z1c2VkZXZlbG9wZXI',NULL,false,'2024-03-15 19:51:49.449+01','2024-03-15 19:51:49.449+01',NULL);"

### Mark platform as configured
kubectl run flowfuse-setup-1 \
  --namespace "pr-$PR_NUMBER" \
  -it --rm \
  --restart=Never \
  --env="PGPASSWORD=$DBPASSWORD" \
  --image bitnami/postgresql:14.10.0-debian-11-r3 \
  -- psql -h flowfuse-pr-$PR_NUMBER-postgresql -U forge -d flowforge -c \
  "INSERT INTO public.\"PlatformSettings\" (\"key\",value,\"valueType\",\"createdAt\",\"updatedAt\")\
    VALUES ('setup:initialised','true',1,'2024-03-15 19:51:52.287','2024-03-15 19:51:52.287'),
           ('team:user:invite:external','true',1,'2024-03-15 19:51:52.287','2024-03-15 19:51:52.287');"

### Configure access token
kubectl run flowfuse-setup-2 \
  --namespace "pr-$PR_NUMBER" \
  -it --rm \
  --restart=Never \
  --env="PGPASSWORD=$DBPASSWORD" \
  --image bitnami/postgresql:14.10.0-debian-11-r3 \
  -- psql -h flowfuse-pr-$PR_NUMBER-postgresql -U forge -d flowforge -c \
  "INSERT INTO public.\"AccessTokens\" (token,\"expiresAt\",scope,\"ownerId\",\"ownerType\",\"refreshToken\",name,\"createdAt\",\"updatedAt\") \
    VALUES ('$INIT_CONFIG_ACCESS_TOKEN_HASH',NULL,'','1','user',NULL,'setup','2024-03-18 10:46:54.055+01','2024-03-18 10:46:54.055+01');"

### Create project type
echo "Creating project type"
curl -ks -w "\n" -XPOST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" \
  -d '{"name":"Default", "description":"DefaultInstanceType","active": true}' \
  https://$FLOWFUSE_URL/api/v1/project-types/

### Create stacks
create_stack "Default" "Default" 30 256 "flowfuse/node-red:$(get_latest_image_tag "4.0.x")"
create_stack "NR-30x" "3.0.x" 30 256 "flowfuse/node-red:latest"
create_stack "NR-31x" "3.1.x" 30 256 "flowfuse/node-red:$(get_latest_image_tag "3.1.x")"


### Link Default to project type
echo "Linking stack to project type"
stackId=$(curl -ks -XGET -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" https://$FLOWFUSE_URL/api/v1/stacks/ | jq -r '.stacks[] | select(.name=="Default") | .id')
curl -ks -XPUT \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" \
  -d '{"properties":{"instances":{"'"$stackId"'":{"active":true}}}}' \
  https://$FLOWFUSE_URL/api/v1/project-types/$projectTypeId

### Delete default team type
echo "Removing default team type"
defaultTeamTypeId=$(curl -ks -XGET -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" https://$FLOWFUSE_URL/api/v1/team-types/ | jq -r '.types[] | select(.name=="starter") | .id')
curl -ks -w "\n" -XDELETE -H "Content-Type: application/json" -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" https://$FLOWFUSE_URL/api/v1/team-types/$defaultTeamTypeId

### Create Starter team type
echo "Creating Starter team type"
curl -ks -w "\n" -XPOST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" \
  -d '{
    "name": "Starter",
    "description": "Starter type",
    "active": true,
    "properties": {
                  "users": {
                      "limit": 5
                  },
                  "devices": {
                      "limit": 10
                  },
                  "features": {
                       "shared-library": false,
                       "projectComms": false,
                       "ha": false,
                       "teamHttpSecurity": false,
                       "customCatalogs": false,
                       "deviceGroups": false,
                       "emailAlerts": false,
                       "protectedInstance": false,
                       "deviceAutoSnapshot": false,
                       "instanceAutoSnapshot": false,
                       "editorLimits": false,
                       "fileStorageLimit": null,
                       "contextLimit": null,
                       "customHostnames":false,
                       "staticAssets":false,
                       "teamBroker":false
                  },
                  "instances": {
                      "'"$projectTypeId"'": {
                          "active": true
                      }
                  }
              },
    "order": 0
  }' https://$FLOWFUSE_URL/api/v1/team-types

### Create Pro team type
echo "Creating Pro team type"
curl -ks -w "\n" -XPOST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" \
-d '{
      "name": "Pro",
      "description": "Pro type",
      "active": true,
      "properties": {
                    "users": {
                        "limit": 5
                    },
                    "devices": {
                        "limit": 10
                    },
                    "features":{
                        "ha":true,
                        "shared-library":true,
                        "projectComms":true,
                        "teamHttpSecurity":true,
                        "fileStorageLimit":null,
                        "contextLimit":null,
                        "customCatalogs":true,
                        "deviceGroups":true,
                        "emailAlerts":true,
                        "deviceAutoSnapshot":true,
                        "instanceAutoSnapshot":true,
                        "protectedInstance":true,
                        "editorLimits":true,
                        "customHostnames":true,
                        "staticAssets":true,
                        "projectHistory":true,
                        "teamBroker":true,
                        "generatedSnapshotDescription":true
                    },
                    "instances": {
                        "'"$projectTypeId"'": {
                            "active": true
                        }
                    }
                },
      "order": 1
    }' https://$FLOWFUSE_URL/api/v1/team-types

### Create Enterprise team type
echo "Creating Enterprise team type"
curl -ks -w "\n" -XPOST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" \
-d '{
      "name": "Enterprise",
      "description": "Enterprise type",
      "active": true,
      "properties": {
                    "users": {
                        "limit": 5
                    },
                    "devices": {
                        "limit": 10
                    },
                    "features": {
                        "ha":true,
                        "shared-library":true,
                        "projectComms":true,
                        "teamHttpSecurity":true,
                        "fileStorageLimit":null,
                        "contextLimit":null,
                        "customCatalogs":true,
                        "deviceGroups":true,
                        "emailAlerts":true,
                        "deviceAutoSnapshot":true,
                        "instanceAutoSnapshot":true,
                        "protectedInstance":true,
                        "editorLimits":true,
                        "customHostnames":true,
                        "staticAssets":true,
                        "bom":true,
                        "projectHistory":true,
                        "teamBroker":true,
                        "gitIntegration": true,
                        "instanceResources":true,
                        "generatedSnapshotDescription":true
                    },
                    "instances": {
                        "'"$projectTypeId"'": {
                            "active": true
                        }
                    }
                },
      "order": 2
    }' https://$FLOWFUSE_URL/api/v1/team-types

### Create template
echo "Creating template"
templateId=$(curl -ks -XPOST \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN" \
  -d '{"name":"initial-template", "active":true, "settings":{"disableEditor":false,"disableTours":false,"httpAdminRoot":"","dashboardUI":"/ui","codeEditor":"monaco","theme":"forge-light","page":{"title":"FlowFuse","favicon":""},"header":{"title":"FlowFuse","url":""},"timeZone":"UTC","palette":{"allowInstall":true,"nodesExcludes":"","denyList":"","modules":[],"catalogue":["https://catalogue.nodered.org/catalogue.json"],"npmrc":""},"modules":{"allowInstall":true,"denyList":""},"httpNodeAuth":{"type":"","user":"","pass":""},"emailAlerts":{"crash":false,"safe":false,"recipients":"owners"}}, "policy":{"disableEditor":true,"disableTours":true,"httpAdminRoot":true,"dashboardUI":true,"codeEditor":true,"theme":true,"page":{"title":false,"favicon":false},"header":{"title":true,"url":false},"timeZone":true,"palette":{"allowInstall":true,"nodesExcludes":false,"denyList":false,"modules":true,"catalogue":true,"npmrc":true},"modules":{"allowInstall":true,"denyList":false},"httpNodeAuth":{"type":true,"user":true,"pass":true},"emailAlerts":{"crash":true,"safe":true,"recipients":true}}}' \
  https://$FLOWFUSE_URL/api/v1/templates/ | jq -r '.id')

### Create teams
create_team "Starter" "Plant Starter"
create_team "Pro" "Plant Pro"
create_team "Enterprise" "Plant Enterprise"


### Create Starter Team Application
echo "Creating Starter Team Application"
starterTeamId=$(get_team_id "Plant Starter")
starterTeamApplicationId=$(curl -ks -XPOST \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN"  \
  -d '{
        "name": "Acme Plant",
        "description": "Acme Plant Starter Application",
        "teamId": "'"$starterTeamId"'"
      }' https://$FLOWFUSE_URL/api/v1/applications | jq -r '.id')

### Create Team Team Application
echo "Creating Pro Team Application"
proTeamId=$(get_team_id "Plant Pro")
proTeamApplicationId=$(curl -ks -XPOST \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN"  \
  -d '{
        "name": "Acme Plant",
        "description": "Acme Plant Pro Application",
        "teamId": "'"$proTeamId"'"
      }' https://$FLOWFUSE_URL/api/v1/applications | jq -r '.id')

### Create Enterprise Team Application
echo "Creating Enterprise Team Application"
enterpriseTeamId=$(get_team_id "Plant Enterprise")
enterpriseTeamApplicationId=$(curl -ks -XPOST \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $INIT_CONFIG_ACCESS_TOKEN"  \
  -d '{
        "name": "Acme Plant",
        "description": "Acme Plant Enterprise Application",
        "teamId": "'"$enterpriseTeamId"'"
      }' https://$FLOWFUSE_URL/api/v1/applications/ | jq -r '.id')

### Create devices
create_device "OP1" "RPI HMI" "Plant Starter"
create_device "OP2" "RPI HMI" "Plant Starter"
create_device "Machine 1" "V1" "Plant Starter"
create_device "Machine 2" "V2" "Plant Starter"
create_device "OP1" "RPI HMI" "Plant Team"
create_device "OP2" "RPI HMI" "Plant Team"
create_device "Machine 1" "V1" "Plant Team"
create_device "Machine 2" "V2" "Plant Team"
create_device "OP1" "RPI HMI" "Plant Enterprise"
create_device "OP2" "RPI HMI" "Plant Enterprise"
create_device "Machine 1" "V1" "Plant Enterprise"
create_device "Machine 2" "V2" "Plant Enterprise"


### Create instances
create_suspended_instance "plant-live-00" $starterTeamApplicationId
create_suspended_instance "plant-develop-00" $starterTeamApplicationId
create_suspended_instance "plant-live-01" $proTeamApplicationId
create_suspended_instance "plant-develop-01" $proTeamApplicationId
create_suspended_instance "plant-live-02" $enterpriseTeamApplicationId
create_suspended_instance "plant-develop-02" $enterpriseTeamApplicationId

### Create users
create_user "member" "${INIT_CONFIG_PASSWORD}"
create_user "viewer" "${INIT_CONFIG_PASSWORD}"

### Assign users to teams
kubectl run flowfuse-setup-4 \
  --namespace "pr-$PR_NUMBER" \
  -it --rm \
  --restart=Never \
  --env="PGPASSWORD=$DBPASSWORD" \
  --image bitnami/postgresql:14.10.0-debian-11-r3 \
  -- psql -h flowfuse-pr-$PR_NUMBER-postgresql -U forge -d flowforge -c \
  "INSERT INTO public.\"TeamMembers\" (\"role\",\"UserId\",\"TeamId\")\
    VALUES
      (30, 2, 1),
      (30, 2, 2),
      (30, 2, 3),
      (10, 3, 1),
      (10, 3, 2),
      (10, 3, 3);"

### Restart flowforge deployment
kubectl --namespace "pr-$PR_NUMBER" rollout restart deployment flowforge
kubectl --namespace "pr-$PR_NUMBER" rollout status deployment flowforge
