#if UNITY_EDITOR
using System;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;

namespace Cryville.Common.Unity {
	[InitializeOnLoad]
	public class ScopedThreadAttacherInjector {
		static readonly Encoding _encoding = new UTF8Encoding(false, true);
		static string _filePath;
		static string _oldSrc;

		static ScopedThreadAttacherInjector() {
			BuildPlayerWindow.RegisterBuildPlayerHandler(opt => HandlePlayerBuild(opt));
		}

		static void HandlePlayerBuild(BuildPlayerOptions opt) {
			try {
				OnPreprocessBuild();
				BuildPlayerWindow.DefaultBuildMethods.BuildPlayer(opt);
			}
			finally {
				OnPostprocessBuild();
			}
		}

		static void OnPreprocessBuild() {
			var il2cppRoot = Environment.GetEnvironmentVariable("UNITY_IL2CPP_PATH");
			if (string.IsNullOrEmpty(il2cppRoot)) {
				_filePath = string.Empty;
				return;
			}
			_filePath = Path.Combine(il2cppRoot, "libil2cpp", "vm", "ScopedThreadAttacher.cpp");
			if (!File.Exists(_filePath)) {
				_filePath = string.Empty;
				return;
			}
			_oldSrc = File.ReadAllText(_filePath, _encoding);
			File.WriteAllText(_filePath, Regex.Replace(_oldSrc, @"~\s*?ScopedThreadAttacher\s*?\(\s*?\)\s*?\{.*\}", "~ScopedThreadAttacher(){}", RegexOptions.Singleline), _encoding);
		}

		static void OnPostprocessBuild() {
			if (string.IsNullOrEmpty(_filePath)) return;
			File.WriteAllText(_filePath, _oldSrc, _encoding);
		}
	}
}
#endif
