using Avalonia.Platform.Storage;
using FubarDev.FtpServer;
using FubarDev.FtpServer.AccountManagement;
using FubarDev.FtpServer.FileSystem.DotNet;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Ursa.Controls;
using 常用工具集.Base;

namespace 常用工具集.ViewModel._02网络相关
{
    public class FTP服务ViewModel : ViewModelBase
    {
        public bool Enabled1 { get; set; } = true;
        public string ButtonName { get; set; } = "开启服务";
        public string Path { get; set; } = "d:/";
        public int Port { get; set; } = 21;
        public string UserName { get; set; } = "admin";
        public string Password { get; set; } = "123456";
        public bool Anonymous { get; set; } = true;
        public int MaxConnectCount { get; set; } = 100;

        public DelegateCommand SelectPathCmd { get; set; }
        public DelegateCommand StartCmd { get; set; }
        public FTP服务ViewModel()
        {
            SelectPathCmd = new DelegateCommand(SelectPathCmdFunc);
            StartCmd = new DelegateCommand(StartCmdFunc);
        }

        private void StartCmdFunc(object obj)
        {
            if (ButtonName == "开启服务")
            {
                bool flag = Start(UserName, Password, Path, Port, Anonymous, MaxConnectCount);
                if (!flag)
                {
                    return;
                }
                Enabled1 = false;
                ButtonName = "停止服务";
            }
            else
            {
                bool flag = Stop();
                if (!flag)
                    return;
                Enabled1 = true;
                ButtonName = "开启服务";
            }
        }

        private async void SelectPathCmdFunc(object obj)
        {
            var sp = GlobalValues.StorageProvider;
            if (sp is null) return;
            var result = await sp.OpenFolderPickerAsync(new FolderPickerOpenOptions()
            {
                Title = "选择FTP主目录",
                AllowMultiple = false,
            });
            if (result == null || result.Count == 0)
            {
                await MessageBox.ShowAsync("文件夹路径不能为空");
                return;
            }
            Path = result.FirstOrDefault()?.Path.LocalPath;
        }

        internal static string UserName1 { get; set; }
        internal static string Password1 { get; set; }
        public ServiceProvider serviceProvider;
        public IFtpServerHost ftpServerHost;
        private bool Start(string userName, string password, string path, int port, bool anonymous, int maxConnectCount)
        {
            try
            {
                UserName1 = userName;
                Password1 = password;
                // 设置依赖项注入
                var services = new ServiceCollection();
                // 使用%TEMP%/TestFtpServer作为根文件夹
                services.Configure<DotNetFileSystemOptions>(opt =>
                {
                    opt.RootPath = path;
                });
                services.Configure<FtpConnectionOptions>(opt => opt.DefaultEncoding = Encoding.GetEncoding("GB2312"));
                // 添加FTP服务器服务
                // DotNetFileSystemProvider = 使用.NET文件系统功能
                // AnonymousMembershipProvider = 仅允许匿名登录
                services.AddFtpServer(builder =>
                {
                    builder.UseDotNetFileSystem(); // 使用.NET文件系统功能
                    if (anonymous)
                    {
                        builder.EnableAnonymousAuthentication();// 允许匿名登录
                    }
                    builder.Services.AddSingleton<IMembershipProvider, TestMembershipProvider>();//用户登录
                });

                // 配置FTP服务器
                services.Configure<FtpServerOptions>(opt =>
                {
                    opt.ServerAddress = "*";
                    opt.Port = port;
                    opt.MaxActiveConnections = maxConnectCount;
                });

                serviceProvider = services.BuildServiceProvider();
                ftpServerHost = serviceProvider.GetRequiredService<IFtpServerHost>();
                ftpServerHost.StartAsync(CancellationToken.None);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }

        public class TestMembershipProvider : IMembershipProvider
        {
            public Task<MemberValidationResult> ValidateUserAsync(string name, string password)
            {
                if (UserName1 == name && password == Password1)
                {
                    var identity = new ClaimsIdentity();
                    identity.AddClaim(new Claim(ClaimTypes.Name, name));
                    identity.AddClaim(new Claim(ClaimTypes.Role, "admin"));
                    return Task.FromResult(new MemberValidationResult(MemberValidationStatus.AuthenticatedUser, new ClaimsPrincipal(identity)));
                }
                return Task.FromResult(new MemberValidationResult(MemberValidationStatus.InvalidLogin));
            }
        }

        private bool Stop()
        {
            try
            {
                // 停止FTP服务器
                ftpServerHost.StopAsync(CancellationToken.None).Wait();
                serviceProvider.Dispose();
                ftpServerHost = null;
                serviceProvider = null;
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    }
}
