using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEditor;
namespace YooAsset.Editor
{
	[Serializable]
	public class ShaderVariantCollectionManifest
	{
		[Serializable]
		public class ShaderVariantElement
		{
			/// 
			///  Pass type to use in this variant.
			/// 
			public PassType PassType;
			/// 
			/// Array of shader keywords to use in this variant.
			/// 
			public string[] Keywords;
		}
		[Serializable]
		public class ShaderVariantInfo
		{
			/// 
			/// Shader asset path in editor.
			/// 
			public string AssetPath;
			/// 
			/// Shader name.
			/// 
			public string ShaderName;
			/// 
			/// Shader variants elements list.
			/// 
			public List ShaderVariantElements = new List(1000);
		}
		/// 
		/// Number of shaders in this collection
		/// 
		public int ShaderTotalCount;
		/// 
		/// Number of total varians in this collection
		/// 
		public int VariantTotalCount;
		/// 
		/// Shader variants info list.
		/// 
		public List ShaderVariantInfos = new List(1000);
		/// 
		/// 添加着色器变种信息
		/// 
		public void AddShaderVariant(string assetPath, string shaderName, PassType passType, string[] keywords)
		{
			var info = GetOrCreateShaderVariantInfo(assetPath, shaderName);
			ShaderVariantElement element = new ShaderVariantElement();
			element.PassType = passType;
			element.Keywords = keywords;
			info.ShaderVariantElements.Add(element);
		}
		private ShaderVariantInfo GetOrCreateShaderVariantInfo(string assetPath, string shaderName)
		{
			var selectList = ShaderVariantInfos.Where(t => t.ShaderName == shaderName && t.AssetPath == assetPath).ToList();
			if (selectList.Count == 0)
			{
				ShaderVariantInfo newInfo = new ShaderVariantInfo();
				newInfo.AssetPath = assetPath;
				newInfo.ShaderName = shaderName;
				ShaderVariantInfos.Add(newInfo);
				return newInfo;
			}
			if (selectList.Count != 1)
				throw new Exception("Should never get here !");
			return selectList[0];
		}
		/// 
		/// 解析SVC文件并将数据写入到清单
		/// 
		public static ShaderVariantCollectionManifest Extract(ShaderVariantCollection svc)
		{
			var manifest = new ShaderVariantCollectionManifest();
			manifest.ShaderTotalCount = ShaderVariantCollectionHelper.GetCurrentShaderVariantCollectionShaderCount();
			manifest.VariantTotalCount = ShaderVariantCollectionHelper.GetCurrentShaderVariantCollectionVariantCount();
			using (var so = new SerializedObject(svc))
			{
				var shaderArray = so.FindProperty("m_Shaders.Array");
				if (shaderArray != null && shaderArray.isArray)
				{
					for (int i = 0; i < shaderArray.arraySize; ++i)
					{
						var shaderRef = shaderArray.FindPropertyRelative($"data[{i}].first");
						var shaderVariantsArray = shaderArray.FindPropertyRelative($"data[{i}].second.variants");
						if (shaderRef != null && shaderRef.propertyType == SerializedPropertyType.ObjectReference && shaderVariantsArray != null && shaderVariantsArray.isArray)
						{
							var shader = shaderRef.objectReferenceValue as Shader;
							if (shader == null)
							{
								throw new Exception("Invalid shader in ShaderVariantCollection file.");
							}
							string shaderAssetPath = AssetDatabase.GetAssetPath(shader);
							string shaderName = shader.name;
							// 添加变种信息
							for (int j = 0; j < shaderVariantsArray.arraySize; ++j)
							{
								var propKeywords = shaderVariantsArray.FindPropertyRelative($"Array.data[{j}].keywords");
								var propPassType = shaderVariantsArray.FindPropertyRelative($"Array.data[{j}].passType");
								if (propKeywords != null && propPassType != null && propKeywords.propertyType == SerializedPropertyType.String)
								{
									string[] keywords = propKeywords.stringValue.Split(' ');
									PassType pathType = (PassType)propPassType.intValue;
									manifest.AddShaderVariant(shaderAssetPath, shaderName, pathType, keywords);
								}
							}
						}
					}
				}
			}
			return manifest;
		}
	}
}