package main

import (
	"fmt"
	"log"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"sort"
	"strconv"

	socketio "github.com/googollee/go-socket.io"
)

func copyBuild(server *socketio.Server, plant string, location string) {
	// Load from environment in real-life code!
	user := os.Getenv("ADM_USER")
	pass := os.Getenv("ADM_PASS")

	// latest build
	latestbuild := lastestBuild()
	src := latestbuild
	plantServer := fmt.Sprintf("\\\\%v\\%v", plant, location)

	// Build PowerShell
	psScript := fmt.Sprintf(`
$secPass = ConvertTo-SecureString '%s' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential ('%s', $secPass)

# Clean up any previous mapped drive
Get-PSDrive -Name "z" -ErrorAction SilentlyContinue | Remove-PSDrive -Force

try {
    # Map a temporary drive "z:" to the destination UNC with creds
    New-PSDrive -Name "z" -PSProvider FileSystem -Root '%s' -Credential $cred | Out-Null

    # Ensure target dir exists on server
    if (-not (Test-Path -Path '%s')) {
        New-Item -ItemType Directory -Path '%s' -Force | Out-Null
    }

	# Remove any .zip files in the destination folder before copying
    Get-ChildItem -Path "z:\" -Filter *.zip -File -ErrorAction SilentlyContinue | Remove-Item -Force -ErrorAction SilentlyContinue

    Write-Host "Starting to copy files to the server"
    Copy-Item -Path '%s' -Destination "z:\" -Force

    #Write-Host "Copy successful completed"
}
catch {
    Write-Host "Error: $_"
}
finally {
    # Always remove the drive
    if (Get-PSDrive -Name "z" -ErrorAction SilentlyContinue) {
        Remove-PSDrive -Name "z"
    }
}
`, pass, user, plantServer, plantServer, plantServer, src)

	msg := fmt.Sprintf("Getting ready to copy %s to %s", src, plantServer)
	fmt.Printf("Getting ready to copy %s to %s", src, plant)

	server.BroadcastToRoom("/", "update", "updateLogs", msg)

	cmd := exec.Command("powershell", "-NoProfile", "-NonInteractive", "-Command", psScript)

	stdout, _ := cmd.StdoutPipe() // writes to the system what the powershell script is doing
	stderr, _ := cmd.StderrPipe()

	if err := cmd.Start(); err != nil {
		server.BroadcastToRoom("/", "update", "updateLogs", fmt.Sprintf("❌ Failed to start copy: %v", err))
		fmt.Printf("❌ Failed to start copy: %v", err)
		return
	}

	// Forward stdout + stderr live
	go streamOutput(stdout, server, "update")
	go streamOutput(stderr, server, "update")

	if err := cmd.Wait(); err != nil {
		server.BroadcastToRoom("/", "update", "updateLogs", fmt.Sprintf("❌ Copy process failed: %v", err))
		return
	}

	server.BroadcastToRoom("/", "update", "updateLogs", "done")
}

func lastestBuild() string {
	// Path to your build folder
	buildDir := "../builds"

	entries, err := os.ReadDir(buildDir)
	if err != nil {
		log.Fatal(err)
	}

	// Regex to match release-1234.zip
	re := regexp.MustCompile(`^release-(\d+)\.zip$`)

	var builds []int
	files := make(map[int]string)

	for _, entry := range entries {
		if entry.IsDir() {
			continue
		}
		name := entry.Name()
		match := re.FindStringSubmatch(name)
		if match != nil {
			num, _ := strconv.Atoi(match[1])
			builds = append(builds, num)
			files[num] = filepath.Join(buildDir, name)
		}
	}

	if len(builds) == 0 {
		log.Fatal("No release zip files found")
	}

	// Sort build numbers ascending
	sort.Ints(builds)
	latest := builds[len(builds)-1]
	latestFile := files[latest]

	return latestFile
}
