' ========================================================
' Installs WebIQ Designer AddOn into workspace directories
'    AddOn provides important features,
'    which are currently missing in WebIQ Designer
' 2026.02-02 adapt to changed workspace folder names
' 2023-01-17 Add folder name to install request
' 2023-01-13 First release
' ========================================================

' Get command line arguments
Set myArgs = WScript.Arguments.Unnamed
bAll = false        ' Flag to install/uninstall for all found projects without asking
bAdd = true         ' Flag: true for install, false for uninstall
bSilent = false     ' Flag for silent operation (no final message box if bAll is true)

sAppInfo = "\.designer\app-info.json"  ' WebIQ file with app info (e.g., project name)
sSrcDir = "addon"  ' Directory name of the addon no "\" at end allowed
NOT_INSTALLED = "*** not installed ***"

' Initialize array for found designer files (workspace project paths)
' We use a dynamic array that grows as needed
ReDim designerFilesArray(0)
designerFilesArray(0) = "" ' Placeholder, will be overwritten
Dim arrayIndex
arrayIndex = 0
sToDo = "install"

' Parse command line arguments
for i = 0 to myArgs.count-1
  if myArgs.item(i)="del" then
    bAdd = false ' Set to uninstall mode
    sToDo = "delete"
  elseif myArgs.item(i)="all" then
    bAll = true  ' Set to all projects mode
  elseif myArgs.item(i)="silent" then
    bSilent = true ' Set to silent mode
  end if
next

Set wshShell = CreateObject( "WScript.Shell" )
appData = wshShell.ExpandEnvironmentStrings( "%APPDATA%" ) ' Get APPDATA environment variable

Set objFSO = CreateObject("Scripting.FileSystemObject")
' Store the full path and name of the script
scriptPathAndName = WScript.ScriptFullName
sDirCur = objFSO.GetParentFolderName(WScript.ScriptFullName) + "\" ' Current script directory

sSourceFullPath = sDirCur + sSrcDir ' Full path to the source addon folder
' WScript.Echo "Current script directory: " & sSourceFullPath

' Check if the source 'addon' folder exists
If Not objFSO.FolderExists(sSourceFullPath) Then
    MsgBox "Folder with installation not found" & vbCrLf & vbCrLf & sSourceFullPath & vbCrLf _
           & vbCrLf & "Installation aborted.", _
           vbCritical, "Startup Error"
    WScript.Quit ' Exit if source folder is missing
End If

' Read version of AddOn from file version.txt
sVersionNew = "???"
sFileVersion = sSourceFullPath + "\json\version.txt" ' Use the full path for the version file
if objFSO.FileExists(sFileVersion) then
  Set oFile = objFSO.OpenTextFile (sFileVersion, 1)
  sVersionNew = oFile.Readline ' Read the version string
  oFile.Close
end if

' Search for WebIQ workspaces with a project (identified by app-info.json)
For Each subFolderLevel1 In objFSO.GetFolder(appData).SubFolders ' Iterate through top-level subfolders in AppData
    ' Iterate through second-level subfolders within subFolderLevel1
    If subFolderLevel1.SubFolders.Count > 0 Then
        For Each subFolderLevel2 In subFolderLevel1.SubFolders
            ' Construct the path to the target file (app-info.json)
            targetFilePath = subFolderLevel2.Path & sAppInfo

            ' Check if the app-info.json file exists
            If objFSO.FileExists(targetFilePath) Then
                ' Adjust array size if more space is needed
                ' arrayIndex - 1 is the last valid index if arrayIndex elements are present
                If arrayIndex > UBound(designerFilesArray) Then
                    ReDim Preserve designerFilesArray(arrayIndex)
                End If
                designerFilesArray(arrayIndex) = subFolderLevel2.Path ' Store the project's root path
                arrayIndex = arrayIndex + 1
            End If
        Next
    End If
Next
iProjects = arrayIndex ' Total number of found WebIQ projects
iCounter  = 0

if (iProjects=0) Then
  sInstalled = "No WebIQ projects found in workspace." + vbCrLf + _
               "You must load a project before you can install the AddOn."
  call MsgBox(sInstalled, vbOkOnly+vbCritical, "Info")
else
  ' Resize the array to the actual number of found projects
  If arrayIndex > 0 Then
      ReDim Preserve designerFilesArray(arrayIndex - 1)
  Else
      ' If no projects were found, but the above block didn't catch it
      WScript.Echo "No projects found, although iProjects > 0. This should not happen."
      WScript.Quit
  End If

  ' Loop over all found workspace projects & ask if add-on should be installed/uninstalled
  iProject = 0

  For Each objPath In designerFilesArray ' Iterate through each found project path
    sTarget = objPath + "\" ' This is the full path to the WebIQ project folder (e.g., C:\...\AppData\WebIQ\Workspace\MyProject)
    sDir = sTarget + sSrcDir ' The full path to the target addon folder within the project (e.g., ...\MyProject\addon)
    arWords = split(sTarget, "\") ' Split the path to get parts for display
    sFile = sTarget + sAppInfo ' The app-info.json path for the current project

    If objFSO.FileExists(sFile) Then ' Double-check app-info.json existence
      iProject = iProject + 1
      sFileWebIq = sTarget & "webiq.json" ' Path to webiq.json for project name
      sInfo = "Workspace " & CStr(iProject) & " of " & CStr(iProjects) ' Project counter for display

      if bAll then ' If 'all' flag is set, skip confirmation dialog
        oAnswer = vbYes
      Else ' Otherwise, show a confirmation message box
        sAddOnVersion = getAddonVersion(sDir)
        if (sAddOnVersion = NOT_INSTALLED) and (bAdd=false) then
          oAnswer = vbNo
        else
          oAnswer = MsgBox("Do you want to " & sToDo & " '" + sVersionNew + "'?" + vbCrLf + vbCrLf + _
                  "Project:         " + getProjectName(sFileWebIq) + vbCrLf + _
                  "Folder:          " + getProjectFolder(sFile) + vbCrLf + _
                  "AddOn:         " + getAddonVersion(sDir) + vbCrLf + _
                  "Workspace:   " + arWords(uBound(arWords)-1) , _
                  vbYesNo+vbQuestion, _
                  "Manage " + sInfo)
          end if
      end if

      If (oAnswer=vbYes) Then ' If user confirmed (or bAll was true)
        if (bAdd) then ' Install mode
          ' WScript.Echo "Source: " & vbCrLf & sSourceFullPath & vbCrLf & _
          '              "Target: " & vbCrLf & sTarget & sSrcDir

          On Error Resume Next
          ' No "\" at end allowed
          ' objFSO.CopyFolder "C:\temp\webiq-addon-install\addon", "C:\Users\stefbaro\AppData\Roaming\webiq-designer\workspace\addon"
          objFSO.CopyFolder sSourceFullPath, sTarget & sSrcDir, True

          ' Check if an error occurred during the copy operation
          If Err.Number <> 0 Then
              WScript.Echo "Copy failed (Error Code " & Err.Number & "): " & Err.Description
              Err.Clear ' Reset error object
          else
              iCounter = iCounter + 1
          End If
          On Error GoTo 0

        else ' Uninstall mode (bAdd is false)
          sTmp = sTarget + "\" + sSrcDir ' Full path to the addon folder inside the project
          if (objFSO.FolderExists(sTmp)) then
            On Error Resume Next ' Enable error handling for deletion
            objFSO.DeleteFolder sTmp, True ' Delete the folder and its contents
            If Err.Number <> 0 Then
                WScript.Echo "Deletion failed (Error Code " & Err.Number & "): " & vbCrLf & Err.Description
                Err.Clear
            End If
            iCounter = iCounter + 1
            On Error GoTo 0 ' Disable error handling
          end if
        End if
      End if
    End if
  Next

  if (bAll) or (iCounter=0) then ' Final message box if 'all' flag was set
    if (bAdd) then
      sAction = "installed"
      sInfo = sVersionNew ' Display the new version if installed
    else
      sAction = "uninstalled"
      sInfo = "AddOn"
    end if
    if (bSilent=false) then ' Only show if not in silent mode
      call MsgBox(sInfo + " " + sAction + " in " + CStr(iCounter) + " projects", vbInformation, "Info")
    end if
  end if
end if

' Get version of the installed add-on within a WebIQ project
' Returns version string or "*** not installed ***"
function getAddonVersion(sDir)
  getAddonVersion = NOT_INSTALLED

  ' sDir should be the path to the AddOn folder within the project (e.g., C:\...\MyProject\addon)
  sFileVersion = sDir + "\json\version.txt"
  if objFSO.FileExists(sFileVersion) then
    Set oFile = objFSO.OpenTextFile (sFileVersion, 1)
    getAddonVersion = oFile.Readline
    oFile.Close
  end if
end function

' Function to get the project name from webiq.json
function getProjectName(sFile)
    getProjectName = "???"
    if objFSO.FileExists(sFile) then
      Set oFile = objFSO.OpenTextFile (sFile, 1)
      Do Until oFile.AtEndOfStream
        sText = trim(oFile.Readline)
        if (left(sText,7) = """name"":") then ' Look for '"name":'
          getProjectName = trim(mid(sText,8))
          ' Remove leading/trailing quotes and trailing comma if present
          if left(getProjectName, 1) = """" then getProjectName = mid(getProjectName, 2)
          if right(getProjectName, 1) = """" then getProjectName = left(getProjectName, len(getProjectName) - 1)
          if right(getProjectName, 1) = "," then getProjectName = left(getProjectName, len(getProjectName) - 2)
          exit function
        end if
      Loop
      oFile.Close
    end if
end function

' Function to get the project folder name from app-info.json (specifically "app_name")
function getProjectFolder(sFile)
    getProjectFolder = "???"
    sContent = ""
    if objFSO.FileExists(sFile) then
      Set oFile = objFSO.OpenTextFile (sFile, 1)
      ' Read entire file content to search for "app_name"
      Do Until oFile.AtEndOfStream
        sContent = sContent + trim(oFile.Readline)
      Loop
      oFile.Close

      ' Example: "app_name":"HMI-Template-v1.1c"
      ' Use RegExp to extract the value for "app_name"
      Dim regex, matches
      Set regex = New RegExp
      regex.Pattern = """app_name""\s*:\s*""([^""]+)""" ' Regex to find "app_name":"value"
      regex.IgnoreCase = True ' Case-insensitive search (though usually not needed for JSON keys)
      Set matches = regex.Execute(sContent)

      If matches.Count > 0 Then
          getProjectFolder = matches.Item(0).SubMatches.Item(0) ' Extract the captured group (the value)
      End If
    end if
end function