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 updateMsg, ApiRequestInfo reqest) { public TEntity Entity { get; } = entity; public TUpdateMsg UpdateMsg { get; } = updateMsg; 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(); if (UpdateEntity(new(entity, msg, req)) is ApiResult result) return result; server.Manager.Save(entity, true); return ToClient(entity).ToItemResult(); } public virtual ApiResult Delete(int id) { server.Manager.Delete(id, true); return ApiResult.Ok(); } protected virtual TEntity CreateNewEntity(TUpdateMsg msg) { return Activator.CreateInstance(); } protected abstract ApiResult? UpdateEntity(EntityUpdate update); protected abstract IDataObject ToClient(TEntity entity); }