using System;
using System.Diagnostics;
using System.IO;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;
using Debug = UnityEngine.Debug;

/// <summary>
/// Generates BuildInfo.cs with git commit information before each build.
/// </summary>
public class BuildInfoGenerator : IPreprocessBuildWithReport {
    public int callbackOrder => 0;

    private const string BuildInfoPath = "Assets/BuildInfo.cs";

    public void OnPreprocessBuild(BuildReport report) { GenerateBuildInfo(); }

    [MenuItem("Build/Generate Build Info")]
    public static void GenerateBuildInfo() {
        string commitHash = GetGitCommitHash();
        string commitShort = commitHash.Length >= 7 ? commitHash.Substring(0, 7) : commitHash;
        string timestamp = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss UTC");

        string content =
                $@"/// <summary>
/// Build information generated at build time.
/// This file is auto-generated by BuildInfoGenerator - do not edit manually.
/// </summary>
public static class BuildInfo {{
    public const string GitCommitHash = ""{commitHash}"";
    public const string GitCommitShort = ""{commitShort}"";
    public const string BuildTimestamp = ""{timestamp}"";
}}
";

        string fullPath = Path.Combine(Application.dataPath, "..", BuildInfoPath);
        File.WriteAllText(fullPath, content);
        AssetDatabase.Refresh();

        Debug.Log($"Generated BuildInfo: {commitShort} at {timestamp}");
    }

    private static string GetGitCommitHash() {
        try {
            var process = new Process {
                StartInfo =
                        new ProcessStartInfo {
                            FileName = "git",
                            Arguments = "rev-parse HEAD",
                            UseShellExecute = false,
                            RedirectStandardOutput = true,
                            RedirectStandardError = true,
                            CreateNoWindow = true,
                            WorkingDirectory = Application.dataPath
                        }
            };

            process.Start();
            string output = process.StandardOutput.ReadToEnd().Trim();
            process.WaitForExit();

            if (process.ExitCode == 0 && !string.IsNullOrEmpty(output)) { return output; }
        } catch (Exception e) { Debug.LogWarning($"Failed to get git commit hash: {e.Message}"); }

        return "unknown";
    }
}
