// Copyright 2020-2023 The Mumble Developers. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file at the root of the
// Mumble source tree or at <https://www.mumble.info/LICENSE>.

//css_ref MumbleInstall.dll
//css_ref Wix_bin\SDK\Microsoft.Deployment.WindowsInstaller.dll;

using System;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.Deployment.WindowsInstaller;
using WixSharp;
using WixSharp.CommonTasks;

public class ServerInstaller : MumbleInstall {

	public const string s_Name = "Mumble Server";
	public const string s_UpgradeGuid = "03E9476F-0F75-4661-BFC9-A9DAEB23D3A0";

	public static string GetMSIPath(string version, string arch) {
		return System.IO.Path.GetFullPath(System.IO.Path.Combine(Environment.CurrentDirectory, "mumble_server-" + new Version(version) + "-" + arch) + ".msi");
	}

	public ServerInstaller(string version, string arch) {
		string[] binaries = {
			"mumble-server.exe",
			"MumbleServer.ice"
		};

		string[] licenses = {
			"qt.txt",
			"gpl.txt",
			"speex.txt",
			"lgpl.txt",
			"Mumble.rtf"
		};

		if (arch == "x64") {
			// 64 bit
			this.Platform = WixSharp.Platform.x64;
			
		} else if (arch == "x86") {
			// 32 bit
			this.Platform = WixSharp.Platform.x86;
		}

		this.Name = ServerInstaller.s_Name;
		this.UpgradeCode = Guid.Parse(ServerInstaller.s_UpgradeGuid);
		this.Version = new Version(version);
		this.OutFileName = "mumble_server-" + this.Version + "-" + arch;
		this.Media.First().Cabinet = "Mumble.cab";

		var progsDir = new Dir(@"%ProgramFiles%");
		var productDir = new Dir("Mumble");
		var installDir = new Dir("server");
		var licenseDir = new Dir("licenses");
		var menuDir = new Dir(@"%ProgramMenu%");
		var shortcutDir = new Dir("Mumble");
		var menuShortcut = new ExeFileShortcut("Mumble Server", "[INSTALLDIR]mumble-server.exe", arguments: "");
		menuShortcut.IconFile = @"..\icons\murmur.ico";
		shortcutDir.Shortcuts = new ExeFileShortcut[] { menuShortcut };
		
		var binaryFiles = new File[binaries.Length];
		var licenseFiles = new File[licenses.Length];
		
		for (int i = 0; i < binaries.Length; i++) {
			binaryFiles[i] = new File(@"..\..\" + binaries[i]);
		}
		
		for (int i = 0; i < licenses.Length; i++) {
			licenseFiles[i] = new File(@"..\..\licenses\" + licenses[i]);
		}

		installDir.Files = binaryFiles;
		licenseDir.Files = licenseFiles;
		
		menuDir.Dirs = new Dir[] { shortcutDir };
		installDir.Dirs = new Dir[] { licenseDir };
		productDir.Dirs = new Dir[] { installDir };
		progsDir.Dirs = new Dir[] { productDir };
		
		this.Dirs = new Dir[] {
			progsDir,
			menuDir
		};
	}
}

class BuildInstaller 
{
	public static void Main(string[] args) {
		string version = "";
		string arch = "";
		string vcRedistRequired = "";
		bool isAllLangs = false;
		bool skipMSIRebuild = false;

		for (int i = 0; i < args.Length; i++) {
			if (args[i] == "--version" && Regex.IsMatch(args[i + 1], @"^([0-9]+\.){2}[0-9]+$")) {
				version = args[i + 1];
			}

			if (args[i] == "--arch" && (args[i + 1] == "x64" || args[i + 1] == "x86")) {
				arch = args[i + 1];
			}

			if (args[i] == "--all-languages") {
				isAllLangs = true;
			}

			if (args[i] == "--vc-redist-required") {
				vcRedistRequired = args[i + 1];
			}

			if (args[i] == "--skip-msi-rebuild") {
				skipMSIRebuild = true;
			}
		}

		if (version != null && arch != null) {
			string msiPath;

			if (!skipMSIRebuild) {
				var srvInstaller = new ServerInstaller(version, arch);
				srvInstaller.Version = new Version(version);
				msiPath = isAllLangs
							? srvInstaller.BuildMultilanguageMsi()
							: srvInstaller.BuildMsi();
			} else {
				Console.WriteLine("INFO - Skipping MSI rebuild.");
				msiPath = ServerInstaller.GetMSIPath(version, arch);
			}

			MumbleInstall.BundleMsi(ServerInstaller.s_Name, Guid.Parse(ServerInstaller.s_UpgradeGuid), msiPath, vcRedistRequired)
			            .Build(msiPath.PathChangeExtension(".exe"));

		} else {
			Console.WriteLine("ERROR - Values for arch or version are null or incorrect!");
			Environment.ExitCode = 0xA0; // Bad argument
		}
	}
}
