'==============================================================
' generateController.vbs
'
' Usage:
'   cscript //nologo generateController.vbs ControllerName "Sub1;Sub2(param1,param2);Sub3"
'
' Generates a controller class file with specified action methods
'==============================================================

Option Explicit

Dim args, controllerName, subsList, subs, fso, fileName, outputPath

' Parse arguments
Set args = WScript.Arguments
If args.Count < 2 Then
    WScript.Echo "Usage: cscript //nologo generateController.vbs ControllerName ""Sub1;Sub2(param1,param2);..."""
    WScript.Echo ""
    WScript.Echo "Example: cscript //nologo generateController.vbs User ""Index;Show(id);Create;Update(id)"""
    WScript.Quit 1
End If

controllerName = args(0)
subsList = args(1)

' Validate controller name format (alphanumeric and underscore only)
If Not IsValidIdentifier(controllerName) Then
    WScript.Echo "Error: Invalid controller name format. Only letters, numbers, and underscores are allowed."
    WScript.Quit 1
End If

' Parse action methods
subs = Split(subsList, ";")

' Determine output path
Set fso = CreateObject("Scripting.FileSystemObject")
outputPath = fso.GetParentFolderName(WScript.ScriptFullName)
fileName = fso.BuildPath(outputPath, controllerName & "Controller.asp")

' Check if file already exists
If fso.FileExists(fileName) Then
    WScript.Echo "Error: Controller file already exists: " & fileName
    WScript.Echo "Delete the existing file or choose a different controller name."
    WScript.Quit 1
End If

' Generate the controller file
Dim content
content = BuildController(controllerName, subs)

' Write to file
Dim file
Set file = fso.CreateTextFile(fileName, True, False)
file.Write content
file.Close
Set file = Nothing
Set fso = Nothing

WScript.Echo "Controller file created: " & fileName
WScript.Echo ""
WScript.Echo "Next steps:"
WScript.Echo "1. Move " & fileName & " to app/controllers/"
WScript.Echo "2. Add this line to app/controllers/autoload_controllers.asp:"
WScript.Echo "   <!--#include file=""" & controllerName & "Controller.asp""-->"
WScript.Echo "3. Register in core/lib.ControllerRegistry.asp:"
WScript.Echo "   RegisterController """ & LCase(controllerName) & "controller"""
WScript.Echo "4. Add routes in public/Default.asp"

'==============================================================
' Build controller content using array-based string building
'==============================================================
Function BuildController(ctrlName, actionsArray)
    Dim parts()
    ReDim parts(500) ' Pre-allocate for performance
    Dim partIdx : partIdx = 0

    Dim className : className = ctrlName & "Controller_Class"
    Dim funcName : funcName = ctrlName & "Controller"

    ' Header comments
    parts(partIdx) = "<%" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "' Auto-generated Controller: " & ctrlName & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "' Generated on " & Now() & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "' Generator: generateController.vbs v1.0" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "'" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "' Remember to:" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "'   1. Add to app/controllers/autoload_controllers.asp" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "'   2. Register in core/lib.ControllerRegistry.asp" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "'   3. Add routes in public/Default.asp" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = vbCrLf & vbCrLf : partIdx = partIdx + 1

    ' Class definition
    parts(partIdx) = "Class " & className & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "    Private m_useLayout" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "    Private m_title" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = vbCrLf : partIdx = partIdx + 1

    ' Class_Initialize
    parts(partIdx) = "    Private Sub Class_Initialize()" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "        m_useLayout = True" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "        m_title = """ & ctrlName & """" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "    End Sub" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = vbCrLf : partIdx = partIdx + 1

    ' useLayout property
    parts(partIdx) = "    Public Property Get useLayout" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "        useLayout = m_useLayout" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "    End Property" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "    Public Property Let useLayout(v)" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "        m_useLayout = v" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "    End Property" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = vbCrLf : partIdx = partIdx + 1

    ' Title property
    parts(partIdx) = "    Public Property Get Title" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "        Title = m_title" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "    End Property" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "    Public Property Let Title(v)" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "        m_title = v" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "    End Property" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = vbCrLf : partIdx = partIdx + 1

    ' Generate action methods
    Dim i, actionDef, namePart, paramsPart, paramsArr
    For i = 0 To UBound(actionsArray)
        actionDef = Trim(actionsArray(i))

        ' Skip empty entries
        If Len(actionDef) > 0 Then
            ' Parse action name and parameters
            If InStr(actionDef, "(") > 0 Then
                namePart = Trim(Left(actionDef, InStr(actionDef, "(") - 1))
                paramsPart = Mid(actionDef, InStr(actionDef, "(") + 1)
                paramsPart = Left(paramsPart, Len(paramsPart) - 1) ' Strip trailing ')'
                paramsPart = Trim(paramsPart)

                ' Validate parameter names
                If Len(paramsPart) > 0 Then
                    paramsArr = Split(paramsPart, ",")
                    Dim j, paramName
                    For j = 0 To UBound(paramsArr)
                        paramName = Trim(paramsArr(j))
                        If Not IsValidIdentifier(paramName) Then
                            WScript.Echo "Error: Invalid parameter name '" & paramName & "' in action '" & actionDef & "'"
                            WScript.Quit 1
                        End If
                    Next
                End If
            Else
                namePart = Trim(actionDef)
                paramsPart = ""
            End If

            ' Validate action name
            If Not IsValidIdentifier(namePart) Then
                WScript.Echo "Error: Invalid action name '" & namePart & "'"
                WScript.Quit 1
            End If

            ' Generate method stub
            parts(partIdx) = "    '---------------------------------------------------------------" & vbCrLf : partIdx = partIdx + 1
            parts(partIdx) = "    ' Action: " & namePart & vbCrLf : partIdx = partIdx + 1
            parts(partIdx) = "    '---------------------------------------------------------------" & vbCrLf : partIdx = partIdx + 1

            If paramsPart = "" Then
                parts(partIdx) = "    Public Sub " & namePart & "()" & vbCrLf : partIdx = partIdx + 1
                parts(partIdx) = "        ' TODO: Implement " & namePart & " action" & vbCrLf : partIdx = partIdx + 1
                parts(partIdx) = "        Response.Write """ & namePart & " action called""" & vbCrLf : partIdx = partIdx + 1
            Else
                parts(partIdx) = "    Public Sub " & namePart & "(" & paramsPart & ")" & vbCrLf : partIdx = partIdx + 1
                parts(partIdx) = "        ' TODO: Implement " & namePart & " action" & vbCrLf : partIdx = partIdx + 1
                parts(partIdx) = "        Response.Write ""<strong>" & namePart & " called</strong><br>""" & vbCrLf : partIdx = partIdx + 1
                parts(partIdx) = "        Response.Write ""Parameters:<br>""" & vbCrLf : partIdx = partIdx + 1

                ' Echo each parameter
                paramsArr = Split(paramsPart, ",")
                For j = 0 To UBound(paramsArr)
                    paramName = Trim(paramsArr(j))
                    parts(partIdx) = "        Response.Write """ & paramName & " = "" & Server.HTMLEncode(CStr(" & paramName & ")) & ""<br>""" & vbCrLf : partIdx = partIdx + 1
                Next
            End If

            parts(partIdx) = "    End Sub" & vbCrLf : partIdx = partIdx + 1
            parts(partIdx) = vbCrLf : partIdx = partIdx + 1
        End If
    Next

    ' End class
    parts(partIdx) = "End Class" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = vbCrLf : partIdx = partIdx + 1

    ' Singleton pattern
    parts(partIdx) = "' Singleton instance" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "Dim " & className & "__Singleton" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "Function " & funcName & "()" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "    If IsEmpty(" & className & "__Singleton) Then" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "        Set " & className & "__Singleton = New " & className & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "    End If" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "    Set " & funcName & " = " & className & "__Singleton" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "End Function" & vbCrLf : partIdx = partIdx + 1
    parts(partIdx) = "%>" & vbCrLf : partIdx = partIdx + 1

    ' Join array for performance
    ReDim Preserve parts(partIdx - 1)
    BuildController = Join(parts, "")
End Function

'==============================================================
' Validate identifier (controller name, action name, parameter name)
'==============================================================
Function IsValidIdentifier(name)
    If IsEmpty(name) Or Len(name) = 0 Then
        IsValidIdentifier = False
        Exit Function
    End If

    Dim i, ch
    For i = 1 To Len(name)
        ch = Mid(name, i, 1)
        ' Allow a-z, A-Z, 0-9, and underscore only
        If Not ((ch >= "a" And ch <= "z") Or _
                (ch >= "A" And ch <= "Z") Or _
                (ch >= "0" And ch <= "9") Or _
                ch = "_") Then
            IsValidIdentifier = False
            Exit Function
        End If
    Next

    IsValidIdentifier = True
End Function
