using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Sozsoft.Mcp.Dtos;
using Sozsoft.Mcp.Services;
using Sozsoft.Platform.Localization;
using Volo.Abp;
using Volo.Abp.Application.Services;
namespace Sozsoft.Mcp;
///
/// MCP uygulama servislerinin ortak tabani. Kullaniciya gorunen metinler platformun
/// PlatformResource kaynagindan okunur; sunucu kaydini cozme ve arac kapisi her
/// serviste ayni davranir.
///
public abstract class McpAppService : ApplicationService
{
protected IMcpServerConfigProvider ServerConfigProvider { get; }
protected McpAppService(IMcpServerConfigProvider serverConfigProvider)
{
ServerConfigProvider = serverConfigProvider;
LocalizationResource = typeof(PlatformResource);
}
/// Etkin sunucu kaydinin DTO hali; kayit yoksa null.
protected async Task ResolveServerConfigAsync()
{
var server = await ServerConfigProvider.GetEffectiveServerAsync();
if (server is null)
{
return null;
}
return new McpServerConfigDto
{
Name = server.Name,
Url = server.Url,
DataSourceCode = server.DataSourceCode,
AllowedTools = [.. ServerConfigProvider.SplitMultiValue(server.AllowedTools)],
MaxRows = server.MaxRows,
AllowWrite = server.AllowWrite,
Description = server.Description,
TenantName = CurrentTenant.Name
};
}
///
/// Kaydi zorunlu kilan islemler icin. Kayit yoksa istemcinin nedenini gorebilecegi bir
/// hata atar.
///
protected async Task RequireServerConfigAsync()
=> await ResolveServerConfigAsync()
?? throw new UserFriendlyException(L[McpErrorCodes.NoServerRecord]);
///
/// Kapali bir araca yapilan cagriyi reddeder: arac sunucu kaydinda kapaliysa ya da
/// kullanicinin uygulamada karsilik gelen yetkisi yoksa. Arac listesini suzmek tek basina
/// yeterli degildir — istemci listede olmayan bir araci da cagirabilir.
///
protected async Task EnsureToolAllowedAsync(string toolName)
{
var config = await RequireServerConfigAsync();
if (!McpToolPolicy.IsAllowed(true, config.AllowWrite, config.AllowedTools, toolName))
{
throw new UserFriendlyException(L[McpErrorCodes.ToolDisabled, toolName, config.Name]);
}
if (McpToolNames.RequiredPermissions.TryGetValue(toolName, out var permission))
{
await AuthorizationService.CheckAsync(permission);
}
return config;
}
/// Istenen satir sayisini sunucu kaydindaki tavana kirpar.
protected static int ResolveMaxRows(McpServerConfigDto config, int requested)
{
var ceiling = config.MaxRows > 0 ? config.MaxRows : McpConsts.DefaultMaxRows;
return requested > 0 ? Math.Min(requested, ceiling) : ceiling;
}
}