using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace axXez.TS3.Bot
{
/// Metadata descriptor for a module type — name, display name, description, namespace, and the CLR type itself.
public class ModuleType
{
/// Short name of the module (class name).
public string Name => Type.Name;
/// Fully qualified name of the module (namespace + class name), e.g. "axXez.Greetings".
public string FullName => $"{Namespace}.{Name}";
/// Human-readable display name. Returns if set, otherwise falls back to .
public string DisplayName => Attribute != null && !string.IsNullOrWhiteSpace(Attribute.DisplayName) ? Attribute.DisplayName : Name;
/// Short description of the module. Returns if set, otherwise empty.
public string Description => Attribute != null && !string.IsNullOrWhiteSpace(Attribute.Description) ? Attribute.Description : string.Empty;
/// Namespace prefix. Returns if set, otherwise the type's CLR namespace.
public string Namespace => Attribute != null && !string.IsNullOrWhiteSpace(Attribute.Namespace) ? Attribute.Namespace : Type.Namespace;
/// The underlying CLR type of the module.
public Type Type { get; private set; }
/// The applied to the module class, or null if none is present.
public ModuleAttribute Attribute { get; private set; }
/// Returns true if this module is compatible with the given server version.
public bool IsCompatibleWith(ServerVersion version)
{
var compat = Attribute?.Compatibility ?? ModuleCompatibility.Any;
return version switch
{
ServerVersion.TS3 => compat.HasFlag(ModuleCompatibility.TS3),
ServerVersion.TS6 => compat.HasFlag(ModuleCompatibility.TS6),
_ => compat.HasFlag(ModuleCompatibility.Unknown)
};
}
internal IReadOnlyList<(MethodInfo Method, CommandAttribute Attr)> CommandMethods { get; private set; }
private ModuleType(Type type)
{
Type = type;
Attribute = type.GetCustomAttribute(false);
CommandMethods = type.GetMethods(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static)
.Select(m => (Method: m, Attr: m.GetCustomAttribute()))
.Where(x => x.Attr != null)
.ToList();
}
internal static ModuleType FromType(Type type) => new ModuleType(type);
internal static ModuleType FromType() where T : Module => new ModuleType(typeof(T));
internal static IEnumerable FromAssembly(Assembly assembly)
=> assembly.GetTypes().Where(x => typeof(Module).IsAssignableFrom(x) && x.IsAbstract == false).Select(FromType);
///
public override string ToString() => $"{Name} ({Type.FullName})";
///
public override int GetHashCode() => Type.GUID.GetHashCode();
///
public override bool Equals(object obj)
=> typeof(ModuleType).IsAssignableFrom(obj.GetType()) && (obj as ModuleType).Type.GUID.Equals(Type.GUID);
}
}