using System;
using System.Collections.Generic;
using System.Linq;

namespace AvatarRefinery.Editor.Core
{
    /// <summary>1カテゴリ分のパフォーマンス評価(PC/Android)</summary>
    [Serializable]
    public sealed class PerfCategoryResult
    {
        public string Category;      // SDKのAvatarPerformanceCategory名
        public string Value;         // 代表値(文字列)
        public string PcRating;      // Excellent/Good/Medium/Poor/VeryPoor/None
        public string AndroidRating;
    }

    /// <summary>診断1回分の結果。UI・レポート・Before/After比較の単位。</summary>
    [Serializable]
    public sealed class DiagnosisReport
    {
        public string AvatarName;
        public DateTime Timestamp;
        public string ToolVersion;

        // 環境
        public string UnityVersion;
        public string SdkVersion;      // 取得できなければ "unknown"
        public bool HasNdmf, HasModularAvatar, HasAao, HasVrcSdk;

        // 診断方式
        /// <summary>NDMFでビルド後の姿を作って性能を算定したか</summary>
        public bool StatsFromBakedAvatar;
        public long BakeMs, StatsMs, RulesMs;
        public string BakeError;

        // パフォーマンス
        public string PcOverall = "None";
        public string AndroidOverall = "None";
        public List<PerfCategoryResult> PerfCategories = new List<PerfCategoryResult>();
        /// <summary>シーン上(ベイク前)の数値。ベイク後と比較表示するため。</summary>
        public List<PerfCategoryResult> PerfCategoriesPreBake = new List<PerfCategoryResult>();

        /// <summary>NDMFベイク中に非破壊ツールが報告したメッセージ(AAOの最適化結果など。参考情報)</summary>
        public List<NdmfMessage> NdmfMessages = new List<NdmfMessage>();

        // 問題
        public List<Issue> Issues = new List<Issue>();
        /// <summary>ルール実行中に発生した例外(診断ツール自身の不具合を隠さない)</summary>
        public List<string> RuleErrors = new List<string>();

        public int Count(Severity s) => Issues.Count(i => i.Severity == s);
        public IEnumerable<Issue> Sorted() => Issues.OrderBy(i => i.Severity).ThenBy(i => i.RuleId);

        public PerfCategoryResult FindCategory(string name) => PerfCategories.FirstOrDefault(c => c.Category == name);
    }
}
