using Pilz.Data; using Pilz.Extensions.Reflection; using Pilz.Net.Extensions; using System.Diagnostics; namespace Pilz.Net.Api.Server; public abstract class BaseHandler(IApiServer server) : IApiHandlerInitializer where TEntity : class, IDataObject where TUpdateMsg : ApiMessage { public class EntityUpdate(TEntity entity, TUpdateMsg message, ApiRequestInfo reqest) { public TEntity Entity { get; } = entity; public TUpdateMsg Message { get; } = message; public ApiRequestInfo Request { get; } = reqest; } public abstract string Route { get; } protected virtual bool RegisterGet => true; protected virtual bool RegisterPut => true; protected virtual bool RegisterDelete => true; public virtual void Initialize(IApiServer server) { var t = GetType(); if (RegisterGet) server.RegisterHandler(t.GetMethod(nameof(Get))!.CreateDelegate(this), new(Route + "/{id}", "GET"), Debugger.IsAttached); if (RegisterPut) server.RegisterHandler(t.GetMethod(nameof(Put))!.CreateDelegate(this), new(Route + "/{id}", "PUT"), Debugger.IsAttached); if (RegisterDelete) server.RegisterHandler(t.GetMethod(nameof(Delete))!.CreateDelegate(this), new(Route + "/{id}", "DELETE"), Debugger.IsAttached); } public virtual ApiResult Get(int id) { if (!server.Manager.Find(id, out TEntity? entity)) return ApiResult.NotFound(); return ToClient(entity).ToItemResult(); } public virtual ApiResult Put(int id, TUpdateMsg msg, ApiRequestInfo req) { if (!server.Manager.Find(id, out TEntity? entity)) return ApiResult.NotFound(); var update = new EntityUpdate(entity, msg, req); if (UpdateEntity(update) is ApiResult result) return result; if (OnSave(update) is ApiResult result2) return result2; return ToClient(entity).ToItemResult(); } public virtual ApiResult Delete(int id) { if (server.Manager.Find(id, out var entity) && OnDelete(entity) is ApiResult result) return result; return ApiResult.Ok(); } protected virtual ApiResult? OnDelete(TEntity entity) { server.Manager.Delete(entity, true); return null; } protected virtual ApiResult? OnSave(EntityUpdate update) { server.Manager.Save(update.Entity, true); return null; } protected virtual TEntity CreateNewEntity(TUpdateMsg msg) { return Activator.CreateInstance(); } protected abstract ApiResult? UpdateEntity(EntityUpdate update); protected abstract IDataObject ToClient(TEntity entity); }