using Minio;
using Minio.DataModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection.Emit;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Net.WebRequestMethods;


namespace test2
{
    class MinioFileManager
    {
        private static string endpoint = "10.40.18.12:9000";
        private static string accessKey = "root";
        private static string secretKey = "root_password";
        private static string bucketName = "hbl";
        private static string url = $"http://{endpoint}/hbl";
        private static MinioClient minioClient=new MinioClient().WithEndpoint(endpoint)
                                            .WithCredentials(accessKey, secretKey)
                                            .Build();
        // Initialize the client with access credentials.

        private static string getObjectNameByUrl(String input) {

            if (input.StartsWith(url))
            {
                string desiredContent = input.Substring(url.Length);
                return desiredContent;
            }
            else
            {
                return input;
            }
        }

        public static async Task<String> UploadFileAsync(string filePath,string objectName=null)
        {
            if (!await minioClient.BucketExistsAsync(new BucketExistsArgs()
                    .WithBucket(bucketName)))
            {
                await minioClient.MakeBucketAsync(new MakeBucketArgs()
                        .WithBucket(bucketName));
            }
            if (objectName == null)  objectName = System.IO.Path.GetFileName(filePath);
            objectName = $"{DateTime.Now.ToString("yyyy-MM-dd")}/{objectName}";
            var putObjectArgs = new PutObjectArgs()
                .WithBucket(bucketName)
                .WithObject(objectName)
                .WithFileName(filePath);
            await minioClient.PutObjectAsync(putObjectArgs);   
            return $"{url}/{objectName}";
        }

        public static async Task DeleteFileAsync(string inputUrl)
        {
            await minioClient.RemoveObjectAsync(new RemoveObjectArgs()
                .WithBucket(bucketName).WithObject(getObjectNameByUrl(inputUrl)));
        }


        /// <summary>列出存储桶里的对象
        /// 列出存储桶里的对象
        /// </summary>
        /// <param name="minio">连接实例</param>
        /// <param name="bucketName">存储桶名称</param>
        /// <param name="prefix">对象的前缀</param>
        /// <param name="recursive">true代表递归查找，false代表类似文件夹查找，以'/'分隔，不查子文件夹</param>
        public static IObservable<Item> ListObjects(Action<Item> action,string prefix = null, bool recursive = true)
        {
            try
            {
                ListObjectsArgs args = new ListObjectsArgs()
                                        .WithBucket(bucketName)
                                        .WithPrefix(prefix)
                                        .WithRecursive(recursive);

                IObservable<Item> observable = minioClient.ListObjectsAsync(args);
                var subscription = observable.Subscribe(new MyObserver(action));
                return observable;
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }
        }
        class MyObserver : IObserver<Item>
        {
            private Action<Item> action;
            public MyObserver(Action<Item> action) {
                this.action = action;
            }
            public void OnCompleted()
            {
                Console.WriteLine("Completed");
            }

            public void OnError(Exception error)
            {
                Console.WriteLine("Error: " + error.Message);
            }

            public void OnNext(Item value)
            {
                action(value);
                Console.WriteLine("Next: " + value.Key);
            }
        }
        public static async Task DownloadFileAsync(string objectName)
        {
            var saveFileDialog = new SaveFileDialog();
            string fileExtension = Path.GetExtension(objectName);
            saveFileDialog.FileName = $"{DateTime.Now.ToString("yyyyMMddHHmmss")}"+ fileExtension;
            if (saveFileDialog.ShowDialog() == DialogResult.OK)
            {
                saveFileDialog.Filter = "All Files (*.*)|*.*";
                var stat = await minioClient.GetObjectAsync(new GetObjectArgs()
                .WithBucket(bucketName)
                .WithObject(getObjectNameByUrl(objectName))
                .WithFile(saveFileDialog.FileName));
                MessageBox.Show("下载成功");
            }
        }
    }

}
