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

namespace Modtorio
{
    public static class Extensions
    {
        public static string GetFriendlyDescription(this ModIssue issue)
        {
            switch (issue)
            {
                default:
                    throw new NotImplementedException();

                case ModIssue.None:
                    return "The mod has no issues.";

                case ModIssue.FileNotFound:
                    return "The Zip file associated with this mod is missing.";

                case ModIssue.InvalidMetadata:
                    return "The mod's metadata is invalid.";

                case ModIssue.InvalidZip:
                    return "The Zip file associated with this mod is invalid.";

                case ModIssue.MissingFileName:
                    return "The filename for this mod is missing.";

                case ModIssue.MissingMetadata:
                    return "The mod's metadata is missing.";

                case ModIssue.MetadataMismatch:
                    return "The mod's stored metadata is not matching with the metadata in the mod's Zip file";

                case ModIssue.MissingDependency:
                    return "The mod is missing one ore more non-optional dependencies with their correct versions.";
            }
        }

        // http://stackoverflow.com/questions/4171140/iterate-over-values-in-flags-enum
        public static IEnumerable<Enum> GetUniqueFlags(this Enum flags)
        {
            ulong flag = 1;

            foreach (var value in Enum.GetValues(flags.GetType()).Cast<Enum>())
            {
                ulong bits = Convert.ToUInt64(value);
                while (flag < bits)
                    flag <<= 1;

                if (flag == bits && flags.HasFlag(value))
                    yield return value;
            }
        }

        public static string Pretty(this TimeSpan timeSpan)
        {
            var secs = (int)timeSpan.TotalSeconds;
            var mins = (int)timeSpan.TotalMinutes;

            if (secs < 2)
                return "Just now";

            if (secs >= 2 && mins < 1)
                return $"{secs} seconds ago";

            return $"{mins} minute{(mins > 1 ? "s" : "")} and {timeSpan.Seconds} second{(timeSpan.Seconds > 1 ? "s" : "")} ago";
        }

        public static string AsIdentifier(this DependencyVersionComparison versionComparison)
        {
            switch (versionComparison)
            {
                default:
                    throw new NotImplementedException();

                case DependencyVersionComparison.Greater:
                    return ">";

                case DependencyVersionComparison.GreaterOrEqual:
                    return ">=";
            }
        }

        public static string Friendly(this DependencyVersionComparison versionComparison)
        {
            switch (versionComparison)
            {
                default:
                    throw new NotImplementedException();

                case DependencyVersionComparison.Greater:
                    return "greater";

                case DependencyVersionComparison.GreaterOrEqual:
                    return "greater or equal";
            }
        }
    }
}
