using System.Collections;
using System.Collections.Generic;
using System;
using UnityEngine;
using System.IO;

public enum BuildType
{
    /// <summary>
    /// 开发人员内部包
    /// </summary>
    Alpha = 0,
    /// <summary>
    /// 无重大错误，需进一步测试消除bug
    /// </summary>
    Beta = 1,
    /// <summary>
    /// 与正式版本几乎一致，不存在导致错误的bug
    /// </summary>
    RC = 2,
    /// <summary>
    /// 最终版，面向客户
    /// </summary>
    Release = 3,
}

public class AppBuildInfo
{

    public const string appBuildFile = "buildNumber.txt";

    /// 版本号 
    /// int
    /// 
    /// 格式设计 UnityEngine.Application.version
    /// 2 147 483 647 [int.MaxValue]
    ///   xxx.xxx.xxx [只允许数字与. 且长度最大只能为11包含2个点]
    /// 
    ///   大版本.小版本.发布渠道
    public static int appVersion
	{
		get
		{
			string verStr = UnityEngine.Application.version;

			// version 格式设计
			// 2 147 483 647 - int.MaxValue
			//   xxx.xxx.xxx 只允许数字与. 且长度最大只能为11包含2个点

			if (string.IsNullOrEmpty(verStr))
			{
				GameDebug.LogError("版本为空");
				return 0 ;
			}

			List<char> list = new List<char>(verStr.Length);
			int pointCount = 0;
			foreach(char ch in verStr)
			{
				if (ch == '.')
				{
					if (++pointCount > 2)
					{
						GameDebug.LogError("版本格式错误: " + UnityEngine.Application.version);
						break;
					}

					list.Add(ch);
				}

				if (ch >= '0' && ch <= '9')
				{
					list.Add(ch);
				}
			}

			verStr = new string(list.ToArray());

			int ver = 0;
			int verSectionFactor = 1;

			string[] arr = verStr.Split('.');
			for(int i = arr.Length - 1; i >= 0; --i)
			{
				int verSection = 0;
				if (arr[i].Length == 0)
				{
					// default 0
				}
				else if (arr[i].Length <= 3)
				{
					int.TryParse(arr[i], out verSection);
				}
				else
				{
					GameDebug.LogError("版本格式错误: " + UnityEngine.Application.version);
					return 0;
				}

				ver += verSection * verSectionFactor;
				verSectionFactor *= 1000;
			}

			return ver;
		}
#if UNITY_EDITOR
        set
        {
            UnityEditor.PlayerSettings.bundleVersion = value.ToString();
        }
#endif
    }

    /// <summary>
    /// 解析版本号,从XXXXXXX格式转换为X.XX.XXX格式
    /// 有缺陷：只支持X.XX.XXX的结构，不支持XX.XX.XXX和XXX.XX.XXX
    /// </summary>
    /// <param name="appVersionStr"></param>
    /// <returns></returns>
    public static string ParseAppVersion(string appVersionStr)
    {
        int factor1 = 1;
        int factor2 = 1000;
        int factor3 = 1000 * 1000;

        int appVersion = 0;
        List<int> versions = new List<int>();
        if (int.TryParse(appVersionStr, out appVersion))
        {
            versions.Add(appVersion / factor3);
            appVersion = appVersion % factor3;
            versions.Add(appVersion / factor2);
            appVersion = appVersion % factor2;
            versions.Add(appVersion / factor1);

            return $"{versions[0].ToString("0")}.{versions[1].ToString("00")}.{versions[2].ToString("000")}";
        }
        else
        {
            GameDebug.LogError($"version parse error,appVersionStr:{appVersionStr}");
            return "";
        }
    }
    
	/// Build 号
	/// int
	/// 
	/// 2 147 483 647 [int.MaxValue]
	/// 年-月-日-秒
	/// 00.00.00.
	public static int buildNumber
    {
        get
        {
            string file = Path.GetFileNameWithoutExtension(appBuildFile);
            TextAsset textAsset = GameResourceManager.Load<TextAsset>(file);
            if (textAsset == null)
            {
                GameDebug.LogError("appBuild文件读取失败,path:" + appBuildFile);
                return 0;
            }
            else
            {
                string[] strArray = textAsset.text.Split(':');
                return int.Parse(strArray[1].Trim());
            }
        }
#if UNITY_EDITOR
        set
        {
            UnityEditor.PlayerSettings.Android.bundleVersionCode = value;
            UnityEditor.PlayerSettings.iOS.buildNumber = value.ToString();
        }
#endif
    }

    /// <summary>
    /// 版本号字符串
    /// </summary>
    public static string appVersionString
    {
        get
        {
            return UnityEngine.Application.version;
        }
    }

    /// <summary>
    /// build号字符串形式
    /// 格式为 年月日.buildType -> 190610.A
    /// </summary>
    public static string appBuildString
    {
        get
        {
            string file = Path.GetFileNameWithoutExtension(appBuildFile);
            TextAsset textAsset = GameResourceManager.Load<TextAsset>(file);
            string content;
            if (textAsset != null)
            {
                content = textAsset.text.ToString();
            }
            else
            {
                content = "0";
                GameDebug.LogError("加载buildNumber配置失败，路径:" + appBuildFile);
            }
            return GetBuildString(content); 
        }
    }

    /// <summary>
    /// 返回build号字符串
    /// </summary>
    /// <param name="buildNumStr"></param>
    /// <returns></returns>
     static string GetBuildString(string buildNumStr)
    {
        try
        {
            string[] strArray = buildNumStr.Split(':');
            buildNumStr = strArray[1].Trim();

            string buildNum = buildNumStr.Substring(0, buildNumStr.Length - 1).Trim();

            string buildTypeStr = "";
            string buildType = buildNumStr.Substring(buildNumStr.Length - 1).Trim();
            buildTypeStr = ParseBuildTypeStr(buildType);
            return string.Format("{0}{1}", buildNum, buildTypeStr);
        }
        catch(Exception e)
        {
            GameDebug.LogError("解析版本号出错,版本号：" + buildNumStr + e);
            return "1906170";
        }
    }

    static string ParseBuildTypeStr(string buildTypeStr)
    {
        if (buildTypeStr.Equals("0"))
        {
             return ".Alpha";
        }
        else if (buildTypeStr.Equals("1"))
        {
            return ".Beta";
        }
        else if (buildTypeStr.Equals("2"))
        {
            return ".RC";
        }
        else if (buildTypeStr.Equals("3"))
        {
            return "";
        }else
        {
            GameDebug.LogError("未定义的buildType,value:" + buildTypeStr);
            return ".Alpha";
        }
    }

    /// <summary>
    /// 得到BuildType的字符串，开头带小数点
    /// </summary>
    /// <returns></returns>
    static string GetBuildTypeStr()
    {
        string file = Path.GetFileNameWithoutExtension(appBuildFile);
        TextAsset textAsset = GameResourceManager.Load<TextAsset>(file);
        string content = "";
        if (textAsset != null)
        {
            content = textAsset.text.ToString();
        }
        else
        {
            GameDebug.LogError("加载buildNumber配置失败，路径:" + appBuildFile);            
        }

        string[] strArray = content.Split(':');
        string buildNumStr = strArray[1].Trim();
        string buildTypeStr = buildNumStr.Substring(buildNumStr.Length - 1);

        return ParseBuildTypeStr(buildTypeStr);
    }

    void test()
    {
        object o = new object();
        
        // ......
        
        
        
        // ......

        if (o == null)
        {
            
        }
    }

    /// <summary>
    /// 版本描述
    /// 格式：v<主版本号>.<副版本号>.<修订版本号>.[附属标记]
    /// </summary>
    /// <returns></returns>
    public static string GetVersionDesc()
    {
        //return string.Format("ver:{0}{1}", UnityEngine.Application.version, GetBuildTypeStr());
        return string.Format("ver:{0}", UnityEngine.Application.version);
    }

    /// <summary>
    /// build号+BuildType，格式为:年月日时包类型 -> 1905120
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static int GetBuild(BuildType type)
    {
        try
        {
            string typeStr = ((int)type).ToString();
            DateTime d = DateTime.Now;

            string yearStr = d.Year.ToString().Substring(2);
            string monthStr = (d.Month < 10) ? string.Format("0{0}", d.Month.ToString()) : d.Month.ToString();
            string dayStr = (d.Day < 10) ? string.Format("0{0}", d.Day.ToString()) : d.Day.ToString();
            string hour = string.Format("{0:D2}", d.Hour);
            string value = string.Format("{0}{1}{2}{3}{4}", yearStr, monthStr, dayStr,hour,typeStr);
            return int.Parse(value);
        }
        catch(Exception e)
        {
            GameDebug.LogError("build号获取出错," + e);
            return 1906170;
        }
    }

    /// <summary>
    /// 得到不带buildType的build号
    /// </summary>
    /// <param name="type"></param>
    /// <returns></returns>
    public static string GetBuildStrWithoutBuildType(BuildType type)
    {
        string buildStr = GetBuild(type).ToString();
        return buildStr.Substring(0, buildStr.Length - 1);
    }


    static BuildType GetBuildType()
    {
        string file = Application.dataPath + "/Resources/buildNumber.txt";
        if (File.Exists(file))
        {
            string content = File.ReadAllText(file);
            string[] strArray = content.Split(':');
            string buildNum = strArray[1];
            int buildType = -1;
            bool suc = int.TryParse(buildNum.Substring(buildNum.Length - 1, 1), out buildType);
            if (!suc)
            {
                GameDebug.LogError($"parse error,buildNum:{buildNum}");
                return BuildType.Alpha;
            }
            else
            {
                return (BuildType)buildType;
            }
        }else
        {
            GameDebug.LogError($"file no exist,file:{file}");
            return BuildType.Alpha;
        }
    }

    /// <summary>
    /// buildType是否是alpha的
    /// </summary>
    public static bool IsAlpha()
    {
        return GetBuildType() == BuildType.Alpha;
    }

#if UNITY_EDITOR
    [UnityEditor.MenuItem("Tools/打印版本和版本号")]
    public static void LogbuildAndVersion()
    {
        GameDebug.Log("版本：" + UnityEngine.Application.version);
        GameDebug.Log("安卓 Build：" + UnityEditor.PlayerSettings.Android.bundleVersionCode);
        GameDebug.Log("IOS Build：" + UnityEditor.PlayerSettings.iOS.buildNumber);
        GameDebug.Log("版本字符串：" + appVersionString);
        GameDebug.Log("Build字符串:" + appBuildString);
        GameDebug.Log(string.Format("adhoc ipa名:PW.{0}.{1}.ah.ipa", appVersionString, appBuildString));
        GameDebug.Log(string.Format("release ipa名:PW.{0}.{1}.pd.ipa", appVersionString, appBuildString));

        GameDebug.LogError("游戏内显示的版本:" + GetVersionDesc());
    }

    [UnityEditor.MenuItem("Tools/Build号/生成新的Build号_Alpha")]
    public static void GenBuildNumber_Alpha()
    {
        GenBuildNumber(BuildType.Alpha);
    }
    [UnityEditor.MenuItem("Tools/Build号/生成新的Build号_Beta")]
    public static void GenBuildNumber_Beta()
    {
        GenBuildNumber(BuildType.Beta);
    }
    [UnityEditor.MenuItem("Tools/Build号/生成新的Build号_RC")]
    public static void GenBuildNumber_RC()
    {
        GenBuildNumber(BuildType.RC);
    }
    [UnityEditor.MenuItem("Tools/Build号/生成新的Build号_Release")]
    public static void GenBuildNumber_Release()
    {
        GenBuildNumber(BuildType.Release);
    }

    public static void GenBuildNumber(BuildType buildType)
    {
        string file = Application.dataPath + "/Resources/buildNumber.txt";
        int build = AppBuildInfo.GetBuild(buildType);
        string content = "build:" + build;

        if (UnityEditor.PlayerSettings.Android.bundleVersionCode == build)
        {
            build += 10;
            GameDebug.Log("build 自加 10 ");
        }
        UnityEditor.PlayerSettings.Android.bundleVersionCode = build;
        UnityEditor.PlayerSettings.iOS.buildNumber = build.ToString();

        File.WriteAllText(file, content);
        GameDebug.Log($"生成新的build号：{build}\npath:{file}");

#if UNITY_EDITOR
        UnityEditor.AssetDatabase.Refresh();
#endif
    }

    [UnityEditor.MenuItem("Test/GenAppVersionNumber")]
    static void TestGenAppVersionNumber()
    {
        UnityEngine.Debug.Log(string.Format("appVersion:{0},还原:{1}", appVersion, ParseAppVersion(appVersion.ToString())));
    }

#endif
}
