using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using Aliyun.Api.LogService;
using Aliyun.Api.LogService.Domain.Log;
using Aliyun.Api.LogService.Domain.LogStore.Index;
using Aliyun.Api.LogService.Infrastructure.Protocol;

namespace MySystem
{
    public class SLS
    {
        //配置AccessKey、服务入口、Project名称、Logstore名称等相关信息。
        //日志服务的服务入口。更多信息，请参见服务入口。
        //此处以杭州为例，其它地域请根据实际情况填写。
        private static string endpoint = "cn-chengdu.log.aliyuncs.com";
        //阿里云访问密钥AccessKey。更多信息，请参见访问密钥。阿里云账号AccessKey拥有所有API的访问权限，风险很高。强烈建议您创建并使用RAM用户进行API访问或日常运维。
        private static string accessKeyId = "LTAI5t9L1WAyzPaQzX57kSxG";
        private static string accessKeySecret = "BqdskHlgU402kHhlpvdTOLsQZ63xKw";
        //Project名称。
        private static string project = "kexiaoshuang";
        //Logstore名称。
        private static string logstore = "aliyun-test-logstore";
        //创建日志服务Client。
        private static ILogServiceClient client = BuildSimpleClient();

        static async Task Main()
        {
            //创建Project。
            var proRes = await client.CreateProjectAsync(project, "des");
            check(proRes);
            Console.WriteLine("Create project success");
            Thread.Sleep(120 * 1000);
            
            //创建Logstore。
            var storeRes = await client.CreateLogStoreAsync(logstore, 3, 2);
            check(storeRes);
            Console.WriteLine("Create logstore success");
            Thread.Sleep(10 * 1000);
            
            //为Logstore创建索引。
            var indRes = await client.CreateIndexAsync(logstore, new IndexLineInfo(new[] {' ', ','}));
            check(indRes);
            Console.WriteLine("Create Index success");
            Thread.Sleep(60 * 1000);

            //向Logstore写入数据。
            // await PostLogs();
            Console.WriteLine("Post logs success");
            Thread.Sleep(3000);
            //查询日志。
            await GetLogs();
        }

        public static async void CreateProject(string name, string detail)
        {
            var proRes = await client.CreateProjectAsync(name, detail);
            check(proRes);
        }

        public static async void CreateLogStore(string logstore)
        {
            var storeRes = await client.CreateLogStoreAsync(logstore, 3, 2, project);
            check(storeRes);
        }

        public static async void CreateIndex(string logstore)
        {
            var indRes = await client.CreateIndexAsync(logstore, new IndexLineInfo(new[] {' ', ','}), project);
            check(indRes);
        }

        public static async Task GetLogs()
        {
            var logsRes = await client.GetLogsAsync(logstore, DateTimeOffset.UtcNow.AddMinutes(-1),
                DateTimeOffset.UtcNow,
                "test", "", 100, 0);
            check(logsRes);
            foreach (var log in logsRes.Result.Logs)
            {
                foreach (var key in log.Keys)
                {
                    log.TryGetValue(key, out var value);
                    Console.WriteLine(key + " : " + value);
                }

                Console.WriteLine("======");
            }
        }

        public static async Task<IList<IDictionary<string, string>>> GetLogs(string logstore, string topic, string query, DateTimeOffset from, int offset = 0, int line = 50)
        {
            var logsRes = await client.GetLogsAsync(logstore, from,
                DateTimeOffset.UtcNow,
                topic, query, line, offset);
            check(logsRes);
            return logsRes.Result.Logs;
        }

        public static async void PostLogs(string logstore, string Topic, string Source, Dictionary<String, String> Contents, Dictionary<String, String> LogTags)
        {
            var response = await client.PostLogStoreLogsAsync(logstore, new LogGroupInfo
            {
                Topic = Topic,
                Source = Source,
                LogTags = LogTags,
                Logs = new List<LogInfo>
                {
                    new LogInfo
                    {
                        Time = DateTimeOffset.Now,
                        Contents = Contents
                        // new Dictionary<String, String>
                        // {
                        //     {"name", "zs"},
                        //     {"age", "18"},
                        //     {"address", String.Empty}
                        // }
                    }
                }
            });
            check(response);
        }

        public static ILogServiceClient BuildSimpleClient()
            => LogServiceClientBuilders.HttpBuilder
                .Endpoint(endpoint, project)
                .Credential(accessKeyId, accessKeySecret)
                .Build();

        public static void check(IResponse res)
        {
            if (!res.IsSuccess)
            {
                throw new ApplicationException(res.Error.ErrorMessage);
            }
        }




        /// <summary>
        /// SLS日志基础方法
        /// </summary>
        /// <param name="createDate"></param>
        /// <param name="topic"></param>
        /// <param name="content"></param>
        /// <param name="otherTags"></param>
        /// <returns></returns>
        public static string WriteLog(DateTime createDate, string topic, string content, Dictionary<string, string> otherTags)
        {
            Dictionary<string, string> tags = new Dictionary<string, string>();
            tags.Add("datetime", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
            tags.Add("date", DateTime.Now.ToString("yyyy-MM-dd"));
            tags.Add("month", DateTime.Now.ToString("yyyy-MM"));
            tags.Add("year", DateTime.Now.ToString("yyyy"));
            foreach(string key in otherTags.Keys)
            {
                tags.Add(key, otherTags[key]);
            }
            SLS.PostLogs("spserver", topic, "47.108.229.115", new Dictionary<string, string>{
                {"content", content}
            }, tags);
            return "ok";
        }
    }
}
